home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus 2002 #11 / Amiga Plus CD - 2002 - No. 11.iso / Games / Saga / source / saga.c < prev    next >
C/C++ Source or Header  |  2002-10-27  |  271KB  |  6,640 lines

  1. #include <exec/exec.h>
  2. #include <intuition/intuition.h>
  3. #include <utility/tagitem.h>
  4. #include <graphics/gfx.h>
  5. #include <clib/intuition_protos.h> // Object
  6. #include <libraries/gadtools.h>    // struct NewMenu
  7. #include <devices/timer.h>         // struct timeval
  8. #include <clib/timer_protos.h>
  9. #include <dos/dosextens.h>         // struct Process
  10. #include <libraries/asl.h>         // ASL_FileRequest
  11. #include <dos/dostags.h>           // SYS_Output
  12. #include <dos/datetime.h>          // struct DateTime
  13. #include <clib/dos_protos.h>
  14. #include <libraries/locale.h>
  15.  
  16. #include <stdlib.h> /* EXIT_SUCCESS, EXIT_FAILURE */
  17. #include <assert.h>
  18.  
  19. #include "amigan.h"
  20.  
  21. #define CATCOMP_NUMBERS
  22. #define CATCOMP_CODE
  23. #define CATCOMP_BLOCK
  24. #include "saga_strings.h"
  25.  
  26. // #define ASSERT
  27.  
  28. #define NORMAL           0
  29. #define GOOD             1
  30. #define BAD              2
  31.  
  32. #define TURNS           20
  33.  
  34. #define UPPER            0
  35. #define LOWER            1
  36.  
  37. #define SCOREDISTANCE   13
  38.  
  39. #define MESSAGEY       473
  40.  
  41. #define AMSIR            0
  42. #define EON              1
  43. #define GEOFU            2
  44. #define ING              3
  45. #define OGAL             4
  46. #define SYGIL            5
  47.  
  48. #define HAGALL           1
  49. #define IS               2
  50. #define JARA             3
  51. #define NIED             4
  52. #define WYNN             5
  53. #define YR               6
  54.  
  55. #define KEYBOARD         0
  56. #define COUNTRY          1
  57. #define COUNTER          2
  58. #define ANYKEY           3
  59.         
  60. // scancodes
  61. #define SCAN_F1         80
  62. #define HELP            95
  63. #define FIRSTQUALIFIER  96
  64. #define LASTQUALIFIER  103
  65. #define KEYUP          128 /* key release */
  66.  
  67. #define BLACK            0
  68. #define WHITE            1
  69. #define LIGHTGREY        2
  70. #define MEDIUMGREY       3
  71. #define DARKGREY         4
  72. #define GREEN            5
  73. #define BLUE             6
  74. #define ORANGE          86
  75. #define PURPLE          87
  76. #define RED             88
  77.  
  78. #define FREY             0
  79. #define LOKI             1
  80. #define NJORD            2
  81. #define ODIN             3
  82. #define THOR             4
  83. #define TYR              5
  84.  
  85. #define ABOUTXPIXEL    312
  86. #define ABOUTYPIXEL     76
  87.  
  88. #define MN_PROJECT       0
  89. #define MN_HELP          1
  90. #define IN_NEW           0
  91. #define IN_OPEN          1
  92. #define IN_SAVE          3
  93. #define IN_SAVEAS        4
  94. #define IN_QUIT          6
  95. #define IN_ABOUT         0
  96.  
  97. #define TITLEBAR         "Saga 1.2a"
  98. #define VERSION          "Saga 1.2a (11.10.2002)"
  99.  
  100. MODULE void place_monsters(void);
  101. MODULE void place_jarls(void);
  102. MODULE FLAG recruit(SLONG recruited, SLONG recruiterhero);
  103. MODULE void flee(SLONG routertype, SLONG router, SLONG routerhero, SLONG routedtype, SLONG routed, SLONG routedhero);
  104. MODULE void wound(SLONG woundertype, SLONG wounder, SLONG wounderhero, SLONG woundedtype, SLONG wounded, SLONG woundedhero);
  105. MODULE void kill(SLONG killertype, SLONG killer, SLONG killerhero, SLONG killedtype, SLONG killed, SLONG killedhero);
  106. MODULE void dobattle(SLONG defendtype, SLONG defender, SLONG attackhero);
  107. MODULE SLONG d6(void);
  108. MODULE SLONG getevent(SLONG mode, SLONG* countertype);
  109. MODULE void say(SLONG position);
  110. MODULE void newhero(SLONG whichhero, FLAG givesord);
  111. MODULE void showcountry(SLONG country);
  112. MODULE void phase1(void);
  113. MODULE void phase2(void);
  114. MODULE void phase3(void);
  115. MODULE void newgame(void);
  116. MODULE void gameloop(void);
  117. MODULE void clearkybd(void);
  118. MODULE void titlescreen(void);
  119. MODULE void gain(SLONG whichhero, SLONG glory, SLONG luck);
  120. MODULE void move(SLONG whichhero);
  121. MODULE void attack(SLONG whichhero);
  122. MODULE void helpabout(void);
  123. MODULE void resettime(void); 
  124. MODULE void anykey(void);
  125. MODULE SLONG getluck(SLONG whichhero);
  126. MODULE FLAG loadgame(FLAG aslwindow);
  127. MODULE void savegame(FLAG saveas);
  128. MODULE SLONG odin_tyr(LONG whichhero, FLAG attacking);
  129. MODULE void gods(SLONG whichhero);
  130. MODULE void pray(SLONG whichhero);
  131. MODULE void amiga_rout(SLONG routed, SLONG routedtype);
  132. MODULE void human_rout(SLONG routedtype, SLONG routed, SLONG routerhero);
  133. MODULE SLONG getmoves(SLONG countertype, SLONG whichcounter, FLAG freyfaxi);
  134. MODULE void faxi_disappear(void);
  135. MODULE void thor(SLONG whichhero);
  136. MODULE void cast(SLONG caster, SLONG whichspell);
  137. MODULE void darken(void);
  138. MODULE SLONG checkcountry(WORD mousex, WORD mousey);
  139. MODULE void infowindow(SLONG countertype, SLONG whichcounter);
  140. MODULE void getdefender(SLONG attackhero, SLONG here);
  141. MODULE FLAG needsord(SLONG countertype, SLONG counter);
  142. MODULE void brosung(SLONG countertype, SLONG whichcounter);
  143. MODULE void flash(SLONG country);
  144. MODULE FLAG assess(SLONG countertype, SLONG counter);
  145. MODULE void promote(SLONG whichhero, SLONG whichjarl);
  146. MODULE void withdraw(SLONG whichhero);
  147. MODULE FLAG asksord(SLONG countertype, SLONG counter, SLONG whichsord);
  148. MODULE void asktreasure(SLONG countertype, SLONG counter, SLONG whichtreasure);
  149. MODULE void pad(STRPTR thestring);
  150. MODULE void print_location(SLONG whichcountry, SLONG index);
  151. MODULE void print_sea(SLONG sea_value, SLONG index);
  152. MODULE void print_hagall(SLONG hagall_value, SLONG index);
  153. MODULE void print_paralyzed(SLONG paralyzed_value, SLONG index);
  154. MODULE void amiga_attack(SLONG attackhero, SLONG defendtype, SLONG defender);
  155. MODULE FLAG ask_faxi(SLONG countertype, SLONG whichcounter);
  156. MODULE void saywho(SLONG countertype, SLONG counter, FLAG comma, FLAG lowercase);
  157. MODULE void callforaid(SLONG passedtype, SLONG passed);
  158. MODULE FLAG attackersleft(void);
  159. MODULE void dospell(SLONG spell, SLONG caster);
  160.  
  161. MODULE struct
  162. {   UBYTE red, green, blue;
  163. } taxcolours[10 + 1] =
  164. {   {  0,  5,  0 }, // tax  0 (unused)
  165.     {  1,  6,  1 }, // tax  1 (unused)
  166.     {  2,  7,  2 }, // tax  2
  167.     {  3,  8,  3 }, // tax  3
  168.     {  4,  9,  4 }, // tax  4
  169.     {  5, 10,  5 }, // tax  5
  170.     {  6, 11,  6 }, // tax  6
  171.     {  7, 12,  7 }, // tax  7
  172.     {  8, 13,  8 }, // tax  8
  173.     {  9, 14,  9 }, // tax  9
  174.     { 10, 15, 10 }  // tax 10
  175. };
  176.  
  177. #define ABOUTLINES     3
  178. struct
  179. {   WORD x, y;
  180.     TEXT text[80 + 1];
  181. } about[ABOUTLINES + 1] =
  182. {   {72, 27},
  183.     {72, 35},
  184.     {72, 51},
  185.     {72, 59}
  186. };
  187.  
  188. #define MENUENTRIES 10
  189. struct NewMenu NewMenu[MENUENTRIES + 1] =
  190. {   { NM_TITLE, "",           0 , 0, 0, 0}, //  0
  191.     {  NM_ITEM, "",          "" , 0, 0, 0}, //  1
  192.     {  NM_ITEM, "",          "" , 0, 0, 0}, //  2
  193.     {  NM_ITEM, NM_BARLABEL,  0 , 0, 0, 0}, //  3
  194.     {  NM_ITEM, "",          "" , 0, 0, 0}, //  4
  195.     {  NM_ITEM, "",          "" , 0, 0, 0}, //  5
  196.     {  NM_ITEM, NM_BARLABEL,  0 , 0, 0, 0}, //  6
  197.     {  NM_ITEM, "",          "" , 0, 0, 0}, //  7
  198.     { NM_TITLE, "",           0 , 0, 0, 0}, //  8
  199.     {  NM_ITEM, "",          "?", 0, 0, 0}, //  9
  200.     {   NM_END, NULL,         0 , 0, 0, 0}  // 10
  201. };
  202.  
  203. // These are better to not be allocated on the stack
  204. MODULE ULONG table1[] = {(8L << 16) + 0,
  205.     0x00000000, 0x00000000, 0x00000000, // 0 (BLACK)
  206.     0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, // 1 (WHITE)
  207.     0xCCCCCCCC, 0xCCCCCCCC, 0xCCCCCCCC, // 2 (LIGHTGREY)
  208.     0x99999999, 0x99999999, 0x99999999, // 3 (MEDIUMGREY)
  209.     0x66666666, 0x66666666, 0x66666666, // 4 (DARKGREY)
  210.     0x66666666, 0xFFFFFFFF, 0x66666666, // 5 (GREEN)
  211.     0x88888888, 0x88888888, 0xFFFFFFFF, // 6 (BLUE)
  212.     0x00000000, 0x00000000, 0x00000000, // 7
  213.     0};
  214. MODULE ULONG table2[] = {(54L << 16) + 74,
  215.     0x99999999, 0x99999999, 0xFFFFFFFF, // 74
  216.     0x99999999, 0xFFFFFFFF, 0x99999999, // 75
  217.     0xFFFFFFFF, 0xCCCCCCCC, 0x99999999, // 76
  218.     0xFFFFFFFF, 0x99999999, 0xFFFFFFFF, // 77
  219.     0xFFFFFFFF, 0xFFFFFFFF, 0x99999999, // 78
  220.     0x00000000, 0x00000000, 0x00000000, // 79
  221.     0x00000000, 0x00000000, 0x00000000, // 80
  222.     0x00000000, 0x00000000, 0x99999999, // 81
  223.     0x00000000, 0x00000000, 0x00000000, // 82
  224.     0x00000000, 0x00000000, 0x99999999, // 83
  225.     0x00000000, 0x00000000, 0x00000000, // 84
  226.     0x00000000, 0x00000000, 0x99999999, // 85
  227.     0xFFFFFFFF, 0x99999999, 0x88888888, // 86 (ORANGE)
  228.     0xFFFFFFFF, 0x88888888, 0xFFFFFFFF, // 87 (PURPLE)
  229.     0xFFFFFFFF, 0x55555555, 0x55555555, // 88 (RED)
  230.     0x00000000, 0x00000000, 0x00000000, // 89
  231.     0x00000000, 0x00000000, 0x00000000, // 90
  232.     0x00000000, 0x00000000, 0x00000000, // 91
  233.     0x00000000, 0x00000000, 0x00000000, // 92
  234.     0x00000000, 0x00000000, 0xFFFFFFFF, // 93
  235.     0x10101010, 0x14141414, 0xFFFFFFFF, // 94
  236.     0x1F1F1F1F, 0x23232323, 0xFFFFFFFF, // 95
  237.     0x2E2E2E2E, 0x32323232, 0xFFFFFFFF, // 96
  238.     0x3D3D3D3D, 0x41414141, 0xFFFFFFFF, // 97
  239.     0x4C4C4C4C, 0x4F4F4F4F, 0xFFFFFFFF, // 98
  240.     0x5B5B5B5B, 0x5E5E5E5E, 0xFFFFFFFF, // 99
  241.     0x6A6A6A6A, 0x6D6D6D6D, 0xFFFFFFFF, // 100
  242.     0x79797979, 0x7C7C7C7C, 0xFFFFFFFF, // 101
  243.     0x87878787, 0x89898989, 0xFFFFFFFF, // 102
  244.     0x96969696, 0x98989898, 0xFFFFFFFF, // 103
  245.     0xA5A5A5A5, 0xA7A7A7A7, 0xFFFFFFFF, // 104
  246.     0xB4B4B4B4, 0xB6B6B6B6, 0xFFFFFFFF, // 105
  247.     0xC3C3C3C3, 0xC4C4C4C4, 0xFFFFFFFF, // 106
  248.     0xD2D2D2D2, 0xD3D3D3D3, 0xFFFFFFFF, // 107
  249.     0xE1E1E1E1, 0xE2E2E2E2, 0xFFFFFFFF, // 108
  250.     0xF0F0F0F0, 0xF1F1F1F1, 0xFFFFFFFF, // 109
  251.     0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, // 110
  252.     0x00000000, 0x00000000, 0xFFFFFFFF, // 111
  253.     0x00000000, 0x88888888, 0xFFFFFFFF, // 112
  254.     0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, // 113
  255.     0x00000000, 0xFFFFFFFF, 0x88888888, // 114
  256.     0x00000000, 0xFFFFFFFF, 0x00000000, // 115
  257.     0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, // 116
  258.     0xFFFFFFFF, 0xDDDDDDDD, 0x00000000, // 117
  259.     0xFFFFFFFF, 0xC5C5C5C5, 0x00000000, // 118
  260.     0xFFFFFFFF, 0xA7A7A7A7, 0x00000000, // 119
  261.     0xFFFFFFFF, 0x89898989, 0x00000000, // 120
  262.     0xFFFFFFFF, 0x72727272, 0x00000000, // 121
  263.     0xFFFFFFFF, 0x54545454, 0x00000000, // 122
  264.     0xFFFFFFFF, 0x36363636, 0x00000000, // 123
  265.     0xFFFFFFFF, 0x1E1E1E1E, 0x00000000, // 124
  266.     0xFFFFFFFF, 0x00000000, 0x00000000, // 125
  267.     0x00000000, 0x00000000, 0x00000000, // 126
  268.     0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, // 127
  269.     0};
  270.  
  271. MODULE struct NewGadget SpeedGadget =
  272. {   300, 312,
  273.     128, 13,
  274.     "",
  275.     NULL,
  276.     NULL,
  277.     NULL,
  278.     NULL,
  279.     NULL
  280. }, CycleGadget[HEROES + 1] = {
  281. {   300, 200,
  282.     128, 13,
  283.     NULL,
  284.     NULL,
  285.     NULL,
  286.     NULL,
  287.     NULL,
  288.     NULL
  289. },
  290. {   300, 216,
  291.     128, 13,
  292.     NULL,
  293.     NULL,
  294.     NULL,
  295.     NULL,
  296.     NULL,
  297.     NULL
  298. },
  299. {   300, 232,
  300.     128, 13,
  301.     NULL,
  302.     NULL,
  303.     NULL,
  304.     NULL,
  305.     NULL,
  306.     NULL
  307. },
  308. {   300, 248,
  309.     128, 13,
  310.     NULL,
  311.     NULL,
  312.     NULL,
  313.     NULL,
  314.     NULL,
  315.     NULL
  316. },
  317. {   300, 264,
  318.     128, 13,
  319.     NULL,
  320.     NULL,
  321.     NULL,
  322.     NULL,
  323.     NULL,
  324.     NULL
  325. },
  326. {   300, 280,
  327.     128, 13,
  328.     NULL,
  329.     NULL,
  330.     NULL,
  331.     NULL,
  332.     NULL,
  333.     NULL
  334. }
  335. };
  336.  
  337. #define HERO_STRENGTH 5
  338. #define HERO_MOVES    4
  339.  
  340. #define RUNES         5
  341.  
  342. SLONG cycleheropos[HEROES + 1] =
  343. {   2,
  344.     3,
  345.     5,
  346.     3,
  347.     0,
  348.     3
  349. };
  350.  
  351. MODULE struct
  352. {   UBYTE red, green, blue;
  353. } herocolour[HEROES + 1] =
  354. { { 15,  12,   6}, // orange
  355.   { 15,   6,   6}, // red
  356.   { 15,  15,   3}, // yellow
  357.   {  6,  15,  15}, // cyan
  358.   { 10,  10,  15}, // light blue
  359.   { 15,   6,  15}  // purple
  360. };
  361. STRPTR trueheroname[HEROES + 1] =
  362. {   "Beowulf",
  363.     "Brunhild",
  364.     "Egil",
  365.     "Ragnar",
  366.     "Siegfried",
  367.     "Starkad"
  368. }, cycleheroname[HEROES + 1] =
  369. {   "  Beowulf:",
  370.     " Brunhild:",
  371.     "     Egil:",
  372.     "   Ragnar:",
  373.     "Siegfried:",
  374.     "  Starkad:"
  375. }, runename[RUNES + 1] =
  376. {   "Amsir",
  377.     "Eon",
  378.     "Geofu",
  379.     "Ing",
  380.     "Ogal",
  381.     "Sygil",
  382. };
  383.  
  384. AGLOBAL struct JarlStruct jarl[JARLS + 1] =
  385. { { 2, 3, "Amleth"    },
  386.   { 3, 3, "Bjarki"    },
  387.   { 3, 3, "Erik"      },
  388.   { 2, 2, "Eyjolf"    },
  389.   { 2, 2, "Gretter"   },
  390.   { 2, 2, "Hagen"     },
  391.   { 2, 3, "Harald"    },
  392.   { 2, 3, "Helgi"     },
  393.   { 2, 2, "Hengist"   },
  394.   { 2, 2, "Horsi"     },
  395.   { 4, 2, "Hrolfwulf" },
  396.   { 4, 2, "Ivar"      },
  397.   { 4, 3, "Kari"      },
  398.   { 2, 3, "Skallagrim"},
  399.   { 3, 3, "Thorolf"   },
  400.   { 2, 3, "Thorvald"  },
  401.   { 3, 3, "Welland"   },
  402.   { 3, 3, "Wiglar"    }
  403. };
  404.  
  405. #define BEOWULF         0
  406. #define BRUNHILD        1
  407. #define EGIL            2
  408. #define RAGNAR          3
  409. #define SIEGFRIED       4
  410. #define STARKAD         5
  411. AGLOBAL struct HeroStruct hero[HEROES + 1];
  412.  
  413. #define BALMUNG         0
  414. #define DRAGVENDILL     1
  415. #define GRAM            2
  416. #define HRUNTING        3
  417. #define LOVI            4
  418. #define TYRFING         5
  419. struct SordStruct sord[SORDS + 1] =
  420. { { "Balmung (+1)"    },
  421.   { "Dragvendill (+2)"},
  422.   { "Gram (+2)"       },
  423.   { "Hrunting (+1)"   },
  424.   { "Lovi (+1)"       },
  425.   { "Tyrfing (+2)"    }
  426. };
  427.  
  428. #define BROSUNGNECKLACE 0
  429. #define FREYFAXI        1
  430. #define MAGICSHIRT      2
  431. #define MAILCOAT        3
  432. struct TreasureStruct treasure[TREASURES + 1] =
  433. { {""         },
  434.   {"Frey Faxi"},
  435.   {""         },
  436.   {""         }
  437. };
  438.  
  439. #define DRAGON 0
  440. #define DROW   1
  441. #define GIANT  2
  442. #define GHOST  3
  443. #define TROLL  4
  444. #define WITCH  5
  445. AGLOBAL struct MonsterStruct monster[MONSTERS + 1] =
  446. { { DRAGON, 10, 1, "Aludreng" },
  447.   { DRAGON, 11, 2, "Fafnir"   },
  448.   { DRAGON, 10, 2, "Glerion"  },
  449.   { DRAGON, 10, 2, "Hallbjorn"},
  450.   { DRAGON,  9, 3, "Istvan"   },
  451.   { DRAGON, 11, 2, "Stigandi" },
  452.   { DROW,    2, 2, "Atli"     },
  453.   { DROW,    3, 1, "Gizur"    },
  454.   { DROW,    3, 1, "Hallgerd" },
  455.   { GHOST,   4, 2, "Gizar"    },
  456.   { GHOST,   4, 1, "Glam"     },
  457.   { GHOST,   4, 0, "Gunnar"   },
  458.   { GHOST,   4, 0, "Hrap"     },
  459.   { GHOST,   4, 1, "Mord"     },
  460.   { GHOST,   4, 1, "Trogrier" },
  461.   { GIANT,   7, 0, "Angantyr" },
  462.   { GIANT,   6, 1, "Hall"     },
  463.   { GIANT,   8, 1, "Storvick" },
  464.   { TROLL,   6, 2, "Grendall" },
  465.   { TROLL,   5, 2, "Hallbjorn"},
  466.   { TROLL,   5, 1, "Hauk"     },
  467.   { TROLL,   6, 1, "Hogshead" },
  468.   { TROLL,   5, 3, "Onund"    },
  469.   { TROLL,   5, 2, "Svinafell"},
  470.   { WITCH,   3, 4, "Gerdrak"  },
  471.   { WITCH,   3, 5, "Grunhild" },
  472.   { WITCH,   4, 4, "Hedin"    }
  473. };
  474.  
  475. /* These are the statistical distribution of the taxation factors:
  476.     4x  2 tax
  477.    10x  3 tax
  478.     3x  4 tax
  479.     3x  5 tax
  480.     6x  6 tax
  481.     4x  7 tax
  482.     1x  8 tax
  483.     2x  9 tax
  484.     3x 10 tax */
  485.  
  486. #define LAND      0
  487. #define SEA       1
  488. #define ISLE      2
  489. #define PENINSULA 3
  490. AGLOBAL struct WorldStruct world[36 + 30] =
  491. {   {590,  39,  3, LAND,      "Finmark"  ,       1, -1, -1, -1, -1, -1, -1, -1}, // 1:1 ( 0) (inland)
  492.     {584, 104,  3, LAND,      "Trondheim",       0,  2,  3, 60, -1, -1, -1, -1}, // 1:2 ( 1)
  493.     {489, 102,  6, LAND,      "Mordaland",       1,  3,  4, 55, 59, 60, -1, -1}, // 1:3 ( 2)
  494.     {573, 173,  2, LAND,      "Upland",          1,  2,  4,  5,  6, -1, -1, -1}, // 1:4 ( 3) (inland)
  495.     {451, 176,  5, LAND,      "Agdar",           2,  3,  5, 48, 49, 54, 55, -1}, // 1:5 ( 4)
  496.     {514, 201,  3, LAND,      "Romeirt",         3,  4,  6,  7, 47, 48, -1, -1}, // 1:6 ( 5)
  497.     {569, 233,  7, LAND,      "Jamtland",        3,  5,  7,  8, 65, -1, -1, -1}, // 2:1 ( 6)
  498.     {512, 262,  6, LAND,      "Vester Gotland",  5,  6,  8,  9, 47, -1, -1, -1}, // 2:2 ( 7)
  499.     {549, 305,  7, LAND,      "Oster Gotland",   6,  7,  9, 63, 65, -1, -1, -1}, // 2:3 ( 8)
  500.     {502, 323,  4, LAND,      "Suder Gotland",   7,  8, 11, 47, 63, -1, -1, -1}, // 2:4 ( 9)
  501.     {420, 287,  6, LAND,      "Juteland",       11, 14, 46, 47, 48, 49, -1, -1}, // 2:5 (10)
  502.     {441, 344,  3, ISLE,      "Scandia",         9, 10, 12, 13, 14, 47, 63, -1}, // 2:6 (11)
  503.     {522, 442,  4, LAND,      "Pomerania",      11, 13, 63, 64, -1, -1, -1, -1}, // 3:1 (12)
  504.     {393, 421,  6, LAND,      "Saxony",         11, 12, 14, 15, 16, 46, -1, -1}, // 3:2 (13)
  505.     {392, 372,  7, LAND,      "Anglia",         10, 11, 13, 46, -1, -1, -1, -1}, // 3:3 (14)
  506.     {305, 383,  7, LAND,      "Fenland",        13, 16, 17, 44, 45, 46, -1, -1}, // 3:4 (15)
  507.     {305, 434, 10, LAND,      "Rhineland",      13, 15, 17, -1, -1, -1, -1, -1}, // 3:5 (16) (inland)
  508.     {242, 428,  9, LAND,      "Frisia",         15, 16, 18, 44, -1, -1, -1, -1}, // 3:6 (17)
  509.     {175, 438,  3, LAND,      "Frankland",      17, 19, 43, 44, -1, -1, -1, -1}, // 4:1 (18)
  510.     { 97, 439, 10, LAND,      "Armorica",       18, 42, 43, -1, -1, -1, -1, -1}, // 4:2 (19)
  511.     { 75, 318,  2, LAND,      "Cornwall",       21, 42, 43, -1, -1, -1, -1, -1}, // 4:3 (20)
  512.     {109, 333, 10, LAND,      "Wessex",         20, 22, 23, 24, 25, 42, 43, -1}, // 4:4 (21)
  513.     {153, 354,  9, LAND,      "Sussex",         21, 23, 24, 43, 44, -1, -1, -1}, // 4:5 (22)
  514.     {190, 329,  6, LAND,      "East Anglia",    22, 24, 44, 45, -1, -1, -1, -1}, // 4:6 (23)
  515.     {148, 313,  3, LAND,      "Mercia",         21, 22, 23, 25, 26, 27, 45, 51}, // 5:1 (24)
  516.     {108, 287,  3, LAND,      "Daffyd",         21, 24, 26, 41, 42, -1, -1, -1}, // 5:2 (25)
  517.     {145, 268,  2, LAND,      "Gwynedd",        24, 25, 27, 41, -1, -1, -1, -1}, // 5:3 (26)
  518.     {186, 217,  8, LAND,      "Northumberland", 24, 26, 28, 41, 51, 52, -1, -1}, // 5:4 (27)
  519.     {178, 157,  3, LAND,      "Dalriada",       27, 29, 30, 40, 41, 52, -1, -1}, // 5:5 (28)
  520.     {222, 130,  5, LAND,      "Caledonia",      28, 30, 52, 57, -1, -1, -1, -1}, // 5:6 (29)
  521.     {230,  85,  2, PENINSULA, "Pictland",       28, 29, 31, 40, 57, 58, 61, 62}, // 6:1 (30)
  522.     {167,  66,  3, ISLE,      "Hebrides",       30, 36, 39, 40, 62, -1, -1, -1}, // 6:2 (31)
  523.     { 62,  40,  3, LAND,      "Thule",          36, 37, -1, -1, -1, -1, -1, -1}, // 6:3 (32)
  524.     { 54, 162,  5, LAND,      "Connacht",       34, 35, 38, 39, -1, -1, -1, -1}, // 6:4 (33)
  525.     {109, 162,  4, LAND,      "Ulster",         33, 35, 39, 40, 41, -1, -1, -1}, // 6:5 (34)
  526.     { 60, 203,  6, LAND,      "Leinster",       33, 34, 41, -1, -1, -1, -1, -1}, // 6:6 (35)
  527.     {134,  32,  0, SEA,       "",               31, 32, 37, 39, -1, -1, -1, -1}, //     (36)
  528.     { 52,  94,  0, SEA,       "",               32, 36, 38, 39, -1, -1, -1, -1}, //     (37)
  529.     { 53, 130,  0, SEA,       "",               33, 37, 39, -1, -1, -1, -1, -1}, //     (38)
  530.     { 82, 118,  0, SEA,       "",               31, 33, 34, 36, 37, 38, 40, -1}, //     (39)
  531.     {137, 165,  0, SEA,       "",               28, 30, 31, 34, 39, 41, -1, -1}, //     (40)
  532.     {116, 225,  0, SEA,       "",               25, 26, 27, 28, 34, 35, 40, 42}, //     (41)
  533.     { 57, 292,  0, SEA,       "",               19, 20, 21, 25, 41, 43, -1, -1}, //     (42)
  534.     {127, 389,  0, SEA,       "",               18, 19, 20, 21, 22, 42, 44, -1}, //     (43)
  535.     {217, 370,  0, SEA,       "",               15, 17, 18, 22, 23, 43, 45, -1}, //     (44)
  536.     {261, 328,  0, SEA,       "",               15, 23, 24, 44, 46, 50, 51, -1}, //     (45)
  537.     {343, 334,  0, SEA,       "",               10, 13, 14, 15, 45, 49, 50, -1}, //     (46)
  538.     {467, 282,  0, SEA,       "Kategatt",        5,  7,  9, 10, 11, 48, -1, -1}, //     (47)
  539.     {445, 229,  0, SEA,       "Skagerrak",       4,  5, 10, 47, 49, -1, -1, -1}, //     (48)
  540.     {376, 270,  0, SEA,       "",                4, 10, 48, 46, 50, 54, -1, -1}, //     (49)
  541.     {311, 268,  0, SEA,       "",               45, 46, 49, 51, 53, 54, -1, -1}, //     (50) (deep waters)
  542.     {240, 258,  0, SEA,       "",               24, 27, 45, 50, 52, 53, -1, -1}, //     (51)
  543.     {248, 193,  0, SEA,       "",               27, 28, 29, 51, 53, 56, 57, -1}, //     (52)
  544.     {324, 196,  0, SEA,       "",               50, 51, 52, 54, 55, 56, -1, -1}, //     (53) (deep waters)
  545.     {379, 186,  0, SEA,       "",                4, 49, 50, 53, 55, -1, -1, -1}, //     (54)
  546.     {386, 124,  0, SEA,       "",                2,  4, 53, 54, 56, 58, 59, -1}, //     (55)
  547.     {318, 134,  0, SEA,       "",               52, 53, 55, 57, 58, -1, -1, -1}, //     (56) (deep waters)
  548.     {267, 133,  0, SEA,       "",               29, 30, 52, 56, 58, -1, -1, -1}, //     (57)
  549.     {338,  90,  0, SEA,       "",               30, 55, 56, 57, 59, 60, 61, -1}, //     (58)
  550.     {427,  73,  0, SEA,       "",                2, 55, 58, 60, -1, -1, -1, -1}, //     (59)
  551.     {456,  27,  0, SEA,       "",                1,  2, 58, 59, 61, -1, -1, -1}, //     (60)
  552.     {341,  47,  0, SEA,       "",               30, 58, 60, 62, -1, -1, -1, -1}, //     (61)
  553.     {257,  44,  0, SEA,       "",               30, 31, 61, -1, -1, -1, -1, -1}, //     (62)
  554.     {509, 385,  0, SEA,       "",                8,  9, 11, 12, 64, 65, -1, -1}, //     (63)
  555.     {587, 404,  0, SEA,       "",               12, 63, 65, -1, -1, -1, -1, -1}, //     (64)
  556.     {587, 345,  0, SEA,       "",                6,  8, 63, 64, -1, -1, -1, -1}  //     (65)
  557. };
  558.  
  559. #define NONE  0
  560. #define HUMAN 1
  561. #define AMIGA 2
  562.  
  563. #define MAXLINES 45
  564. #define LEFTSIDE  0
  565. #define RIGHTSIDE 1
  566.  
  567. IMPORT  struct ExecBase*      SysBase;
  568.  
  569. AGLOBAL struct GfxBase*       GfxBase       = NULL;
  570. AGLOBAL struct GadToolsBase*  GadToolsBase  = NULL;
  571. AGLOBAL struct IntuitionBase* IntuitionBase = NULL;
  572. AGLOBAL struct LocaleBase*    LocaleBase    = NULL;
  573. AGLOBAL struct Library*       TimerBase     = NULL;
  574. AGLOBAL struct ASLBase*       ASLBase       = NULL;
  575.  
  576. AGLOBAL struct Window        *MainWindowPtr = NULL,
  577.                              *HelpWindowPtr = NULL,
  578.                              *InfoWindowPtr = NULL;
  579. AGLOBAL UWORD                 DisplayDepth  = DEPTH;
  580.  
  581. MODULE  WORD                  speed         = 4;
  582. MODULE  UBYTE                 IOBuffer[600];
  583. MODULE  ULONG                 DisplayID     = HIRES_KEY | PAL_MONITOR_ID | LACE,
  584.                               DisplayWidth  = SCREENXPIXEL,
  585.                               DisplayHeight = SCREENYPIXEL;
  586. MODULE  struct RDArgs*        ArgsPtr       = NULL;
  587. MODULE  struct FileRequester* ASLRqPtr      = NULL;
  588. MODULE  struct Screen*        ScreenPtr     = NULL;
  589. MODULE  struct Process*       ProcessPtr    = NULL;
  590. MODULE  struct Menu*          MenuPtr       = NULL;
  591. MODULE  struct VisualInfo*    VisualInfoPtr = NULL;
  592. MODULE  APTR                  OldWindowPtr  = NULL;
  593. MODULE  FLAG                  gameover,
  594.                               loaded,
  595.                               cliload                    = FALSE;
  596. MODULE  SLONG                 faxirides,
  597.                               tickwait                   = 7, // measured in intuiticks (10ths of a second)
  598.                               turn,
  599.                               order[HEROES + 1];
  600. MODULE  TEXT                  abouttitle[80 + 1],
  601.                               saystring[256 + 1],
  602.                               numberstring[13 + 1],
  603.                               titlestring[80 + 1],
  604.                               pathname[256 + 1],
  605.                               line[2][MAXLINES + 1][80 + 1];
  606. MODULE  struct Gadget        *SpeedGadgetPtr             = NULL,
  607.                              *CycleGadgetPtr[HEROES + 1] = {NULL, NULL, NULL, NULL, NULL, NULL},
  608.                              *GListPtr                   = NULL,
  609.                              *PrevGadgetPtr              = NULL;
  610. MODULE  struct LocaleInfo     li;
  611. MODULE  STRPTR                CycleOptions[4],
  612.                               monstertypes[6],
  613.                               runedesc[RUNES + 1];
  614.  
  615. #define ONEKEY_YES           0
  616. #define ONEKEY_NO            1
  617. #define ONEKEY_WITHDRAW      2
  618. #define ONEKEY_RESTART       3
  619. #define ONEKEY_TRANSFER      4
  620. #define ONEKEY_GLORY         5
  621. #define ONEKEY_LUCK          6
  622. #define ONEKEYS              ONEKEY_LUCK
  623.  
  624. TEXT onekey[ONEKEYS + 1] =
  625. {   'Y', 'N', 'W', 'R', 'T', 'G', 'L'
  626. };
  627.  
  628. MODULE void place_monsters(void)
  629. {   /* .taken = FALSE: the monster is in the "pile of monsters" (spare).
  630.                 TRUE : the monster is either on the board or dead. */
  631.  
  632.     SLONG whichhero, whichmonster, whichtreasure;
  633.     FLAG  available, ok;
  634.  
  635.     for (whichhero = 0; whichhero <= HEROES; whichhero++)
  636.     {   if (hero[whichhero].alive)
  637.         {   available = FALSE;
  638.             for (whichmonster = 0; whichmonster <= MONSTERS; whichmonster++)
  639.             {   if (!monster[whichmonster].taken)
  640.                 {   available = TRUE;
  641.                     break;
  642.             }   }
  643.             if (available)
  644.             {   do
  645.                 {   whichmonster = rand() % (MONSTERS + 1);
  646.                 } while (monster[whichmonster].taken);
  647.                 monster[whichmonster].taken    =
  648.                 monster[whichmonster].alive    = TRUE;
  649.                 monster[whichmonster].where    = rand() % 36;
  650.                 monster[whichmonster].sea      = NORMAL;
  651.                 monster[whichmonster].hagall   = FALSE;
  652.  
  653.                 if (monster[whichmonster].species == DRAGON)
  654.                 {   ok = FALSE;
  655.                     for (whichtreasure = 0; whichtreasure <= TREASURES; whichtreasure++)
  656.                     {   if (!treasure[whichtreasure].taken)
  657.                         {   ok = TRUE; // at least one treasure is available
  658.                             break; // for speed
  659.                     }   }
  660.                     if (ok)
  661.                     {   do
  662.                         {   whichtreasure = rand() % (TREASURES + 1);
  663.                         } while (treasure[whichtreasure].taken);
  664.                         treasure[whichtreasure].taken         = TRUE;
  665.                         treasure[whichtreasure].possessortype = MONSTER;
  666.                         treasure[whichtreasure].possessor     = whichmonster;
  667.                         treasure[whichtreasure].where         = -1;
  668.  
  669.                         monster[whichmonster].wealth = 0;
  670.                     } else
  671.                     {   monster[whichmonster].wealth = 20;
  672.                 }   }
  673.                 else
  674.                 {   monster[whichmonster].wealth = 0;
  675.                 }
  676.                 // we don't unslot newborn counters
  677.                 move_monster(whichmonster, FALSE);
  678. }   }   }   }
  679.  
  680. MODULE void place_jarls(void)
  681. {   FLAG  available;
  682.     SLONG whichhero, whichjarl;
  683.  
  684.     for (whichhero = 0; whichhero <= HEROES; whichhero++)
  685.     {   if (hero[whichhero].alive)
  686.         {   available = FALSE;
  687.             for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
  688.             {   if (!jarl[whichjarl].taken)
  689.                 {   available = TRUE;
  690.                     break;
  691.             }   }
  692.             if (available)
  693.             {   do
  694.                 {   whichjarl = rand() % (JARLS + 1);
  695.                 } while (jarl[whichjarl].taken);
  696.                 jarl[whichjarl].taken     =
  697.                 jarl[whichjarl].alive     = TRUE;
  698.                 jarl[whichjarl].wealth    = 0;
  699.                 jarl[whichjarl].where     =
  700.                 jarl[whichjarl].homewhere = rand() % 36;
  701.                 jarl[whichjarl].hero      = -1;
  702.                 jarl[whichjarl].sea       = NORMAL;
  703.                 jarl[whichjarl].hagall    =
  704.                 jarl[whichjarl].loseturn  = FALSE;
  705.                 hidejarl(whichjarl, FALSE);
  706.                 // we don't unslot newborn counters
  707.                 move_jarl(whichjarl, FALSE);
  708. }   }   }   }
  709.  
  710. int main(int argc, char** argv)
  711. {   struct TextAttr             Topaz8 =
  712.     {   (STRPTR) "topaz.font", 8, FS_NORMAL, FPF_ROMFONT | FPF_DESIGNED
  713.     };
  714.     struct DateTime             DateTime;
  715.     struct ScreenModeRequester* smr;
  716.     BPTR                        FileHandle /* = NULL */ ;
  717.     FLAG                        ok;
  718.     TEXT                        datestring[LEN_DATSTRING],
  719.                                 weekdaystring[LEN_DATSTRING],
  720.                                 tempstring[1 + 1],
  721.                                 smrstring[80 + 1];
  722.     SLONG                       whichcountry, whichhero,
  723.                                 args[7] = {0L, 0L, 0L, 0L, 0L, 0L, 0L};
  724.     UWORD                       Pens[13] =
  725.     {   BLACK,     /* DETAILPEN            text in title bar */
  726.         WHITE,     /* BLOCKPEN             fill title bar */
  727.         WHITE,     /* TEXTPEN              regular text on BACKGROUNDPEN (was BLACK) */
  728.         LIGHTGREY, /* SHINEPEN             bright edge */
  729.         DARKGREY,  /* SHADOWPEN            dark edge */
  730.         BLUE,      /* FILLPEN              filling active window borders
  731.                                            and selected gadgets */
  732.         BLACK,     /* FILLTEXTPEN          text rendered over FILLPEN */
  733.         BLACK,     /* BACKGROUNDPEN        background colour (was BLUE) */
  734.         ORANGE,    /* HIGHLIGHTTEXTPEN     highlighted text on BACKGROUNDPEN
  735.                                            and used against BLOCKPEN in ASL
  736.                                            save requesters */
  737.         BLACK,     /* BARDETAILPEN         text/detail in screen-bar/menus */
  738.         WHITE,     /* BARBLOCKPEN          screen-bar/menus fill */
  739.         BLACK,     /* BARTRIMPEN           trim under screen-bar */
  740.         (UWORD) ~0 /* and used against BLOCKPEN in ASL save requesters */
  741.     };
  742.  
  743. /* Colour allocations are as follows:
  744.     colours 0-6 are used by the game itself.
  745.     colour 7 is the black of the map.
  746.     colours 8-43 are map land colours, except that
  747.     colours 17-19 are mouse pointer colours.
  748.     colours 44-73 are map sea colours.
  749.     colour 74 is hero counter colour (blue).
  750.     colour 75 is jarl counter colour (green).
  751.     colour 76 is monster counter colour (orange).
  752.     colour 77 is treasure counter colour (purple).
  753.     colour 78 is sword counter colour (yellow).
  754.     colour 79 is the black of the counters.
  755.     colour 80 is Scandian coastline.
  756.     colour 81 is Scandian sea.
  757.     colour 82 is Pictish coastline.
  758.     colour 83 is Pictish sea.
  759.     colour 84 is Hebridean coastline.
  760.     colour 85 is Hebridean sea.
  761.     colours 86-88 are used by the game itself.
  762.     colour 89 is Suder Gotland land (replacement for colour 17).
  763.     colour 90 is Juteland land (replacement for colour 18).
  764.     colour 91 is Scandian land (replacement for colour 19).
  765.     colours 92-110 are used for the Saga logo.
  766.     colours 111-125 (and others) are used for the Amigan Software logo.
  767.     colour 126 is selected menu text.
  768.     colour 127 is selected menu background.
  769.  
  770.     Start of program.
  771.  
  772.     version embedding into executable */
  773.     if (0) /* that is, never */
  774.     {   Printf("%s\n", VERSION);
  775.     }
  776.  
  777.     // before the first possible point of failure
  778.     init_counters();
  779.     for (whichcountry = 0; whichcountry <= 65; whichcountry++)
  780.     {   world[whichcountry].hero = -1;
  781.     }
  782.     pathname[0] = 0;
  783.  
  784.     if (!(IntuitionBase = (struct IntuitionBase *) OpenLibrary("intuition.library", 39L)))
  785.     {   strcpy(saystring, "Saga: Can't open intuition.library V39+!)\n");
  786.         Write(Output(), saystring, strlen(saystring));
  787.         cleanexit(EXIT_FAILURE);
  788.     }
  789.  
  790.     ProcessPtr = (struct Process *) FindTask(NULL);
  791.  
  792.     if (SysBase->LibNode.lib_Version < 36L)
  793.     {   DisplayAlert(AT_Recovery, "\0\20\20Saga: Can't open exec.library V36+!\0", 24);
  794.     cleanexit(EXIT_FAILURE);
  795.     }
  796.  
  797.     /* From this point onwards, we can be sure we have Kickstart 2.0+...
  798.  
  799.     NOTES FOR TRANSLATORS:
  800.       MSG_CHAR_FOO messages are single-character strings which are the
  801.     first letter of the relevant word. MSG_UNCHAR_FOO messages are the
  802.     rest of the word. Eg. in English, MSG_CHAR_GLORY is "G" and
  803.     MSG_UNCHAR_GLORY is "lory". They must each be different among their
  804.     'set' (yes/no, glory/luck, restart/transfer/withdraw). */
  805.  
  806.     li.li_Catalog = NULL;
  807.     if (LocaleBase = OpenLibrary("locale.library", 38))
  808.     {   li.li_LocaleBase   = LocaleBase;
  809.         li.li_Catalog      = OpenCatalog(NULL, "Saga.catalog", TAG_DONE);
  810.     }
  811.     strcpy(tempstring, GetCatalogStr(li.li_Catalog, MSG_CHAR_YES,      "Y"));
  812.     onekey[ONEKEY_YES]      = tempstring[0];
  813.     strcpy(tempstring, GetCatalogStr(li.li_Catalog, MSG_CHAR_NO,       "N"));
  814.     onekey[ONEKEY_NO]       = tempstring[0];
  815.     strcpy(tempstring, GetCatalogStr(li.li_Catalog, MSG_CHAR_WITHDRAW, "W"));
  816.     onekey[ONEKEY_WITHDRAW] = tempstring[0];
  817.     strcpy(tempstring, GetCatalogStr(li.li_Catalog, MSG_CHAR_RESTART,  "R"));
  818.     onekey[ONEKEY_RESTART]  = tempstring[0];
  819.     strcpy(tempstring, GetCatalogStr(li.li_Catalog, MSG_CHAR_TRANSFER, "T"));
  820.     onekey[ONEKEY_TRANSFER] = tempstring[0];
  821.     strcpy(tempstring, GetCatalogStr(li.li_Catalog, MSG_CHAR_GLORY,    "G"));
  822.     onekey[ONEKEY_GLORY]    = tempstring[0];
  823.     strcpy(tempstring, GetCatalogStr(li.li_Catalog, MSG_CHAR_LUCK,     "L"));
  824.     onekey[ONEKEY_LUCK]     = tempstring[0];
  825.     CycleOptions[0] = GetCatalogStr(li.li_Catalog, MSG_GADGET_NONE, "None");
  826.     CycleOptions[1] = GetCatalogStr(li.li_Catalog, MSG_HUMAN, "Human");
  827.     CycleOptions[2] = "Amiga";
  828.     CycleOptions[3] = NULL;
  829.     strcpy(abouttitle, GetCatalogStr(li.li_Catalog, MSG_ABOUT, "About"));
  830.     strcat(abouttitle, " Saga");
  831.     strcpy(about[0].text, TITLEBAR);
  832.     about[1].text[0] = 0;
  833.     DateTime.dat_Format          = FORMAT_DOS;
  834.     DateTime.dat_Flags           = NULL;
  835.     DateTime.dat_StrDate         = "11-Oct-02";
  836.     DateTime.dat_StrDay          = NULL;
  837.     DateTime.dat_StrTime         = NULL;
  838.     DateTime.dat_Stamp.ds_Minute = 0;
  839.     DateTime.dat_Stamp.ds_Tick   = 0;
  840.     if (StrToDate(&DateTime))
  841.     {   // DateTime.dat_Stamp is now filled
  842.         DateTime.dat_Format  = FORMAT_DEF;
  843.         DateTime.dat_Flags   = NULL;
  844.         DateTime.dat_StrDate = datestring;
  845.         DateTime.dat_StrDay  = weekdaystring;
  846.         DateTime.dat_StrTime = NULL;
  847.         if (DateToStr(&DateTime))
  848.         {   strcpy(about[1].text, weekdaystring);
  849.             strcat(about[1].text, " ");
  850.             strcat(about[1].text, datestring);
  851.     }   }
  852.     strcpy(about[2].text, "© 2002 Amigan Software");
  853.     strcpy(about[3].text, GetCatalogStr(li.li_Catalog, MSG_BY, "By"));
  854.     strcat(about[3].text, " James R. Jacobs");
  855.     monstertypes[0] = GetCatalogStr(li.li_Catalog, MSG_DRAGON, "Dragon");
  856.     monstertypes[1] = GetCatalogStr(li.li_Catalog, MSG_DROW  , "Drow"  );
  857.     monstertypes[2] = GetCatalogStr(li.li_Catalog, MSG_GIANT , "Giant" );
  858.     monstertypes[3] = GetCatalogStr(li.li_Catalog, MSG_GHOST , "Ghost" );
  859.     monstertypes[4] = GetCatalogStr(li.li_Catalog, MSG_TROLL , "Troll" );
  860.     monstertypes[5] = GetCatalogStr(li.li_Catalog, MSG_WITCH , "Witch" );
  861.     runedesc[0] = GetCatalogStr(li.li_Catalog, MSG_THE_GODS, "rune of the gods");
  862.     runedesc[1] = GetCatalogStr(li.li_Catalog, MSG_TIME    , "rune of time"    );
  863.     runedesc[2] = GetCatalogStr(li.li_Catalog, MSG_PROPERTY, "rune of property");
  864.     runedesc[3] = GetCatalogStr(li.li_Catalog, MSG_HEALING , "rune of healing" );
  865.     runedesc[4] = GetCatalogStr(li.li_Catalog, MSG_FURY    , "rune of fury"    );
  866.     runedesc[5] = GetCatalogStr(li.li_Catalog, MSG_THE_SUN , "rune of the sun" );
  867.     for (whichcountry = 36; whichcountry <= 39; whichcountry++)
  868.     {   world[whichcountry].name = GetCatalogStr(li.li_Catalog, MSG_ATLANTIC_OCEAN , "Atlantic Ocean" );
  869.     }
  870.     for (whichcountry = 40; whichcountry <= 42; whichcountry++)
  871.     {   world[whichcountry].name = GetCatalogStr(li.li_Catalog, MSG_IRISH_SEA      , "Irish Sea"      );
  872.     }
  873.     for (whichcountry = 43; whichcountry <= 44; whichcountry++)
  874.     {   world[whichcountry].name = GetCatalogStr(li.li_Catalog, MSG_ENGLISH_CHANNEL, "English Channel");
  875.     }
  876.     for (whichcountry = 45; whichcountry <= 62; whichcountry++)
  877.     {   if (whichcountry < 47 || whichcountry > 48)
  878.         {   world[whichcountry].name = GetCatalogStr(li.li_Catalog, MSG_NORTH_SEA  , "North Sea"      );
  879.     }   }
  880.     for (whichcountry = 63; whichcountry <= 65; whichcountry++)
  881.     {   world[whichcountry].name = GetCatalogStr(li.li_Catalog, MSG_BALTIC_SEA     , "Baltic Sea"     );
  882.     }
  883.     treasure[BROSUNGNECKLACE].name = GetCatalogStr(li.li_Catalog, MSG_BROSUNG_NECKLACE, "Brosung Necklace");
  884.     treasure[MAGICSHIRT].name      = GetCatalogStr(li.li_Catalog, MSG_MAGIC_SHIRT     , "Magic Shirt"     );
  885.     treasure[MAILCOAT].name        = GetCatalogStr(li.li_Catalog, MSG_MAIL_COAT       , "Mail Coat"       );
  886.     NewMenu[0].nm_Label   = GetCatalogStr(li.li_Catalog, MSG_PROJECT         , "Project"   );
  887.     NewMenu[1].nm_Label   = GetCatalogStr(li.li_Catalog, MSG_NEW             , "New"       );
  888.     NewMenu[1].nm_CommKey = GetCatalogStr(li.li_Catalog, MSG_SHORTCUT_NEW    , "N"         );
  889.     NewMenu[2].nm_Label   = GetCatalogStr(li.li_Catalog, MSG_OPEN            , "Open..."   );
  890.     NewMenu[2].nm_CommKey = GetCatalogStr(li.li_Catalog, MSG_SHORTCUT_OPEN   , "O"         );
  891.     NewMenu[4].nm_Label   = GetCatalogStr(li.li_Catalog, MSG_SAVE            , "Save"      );
  892.     NewMenu[4].nm_CommKey = GetCatalogStr(li.li_Catalog, MSG_SHORTCUT_SAVE   , "S"         );
  893.     NewMenu[5].nm_Label   = GetCatalogStr(li.li_Catalog, MSG_SAVE_AS         , "Save As...");
  894.     NewMenu[5].nm_CommKey = GetCatalogStr(li.li_Catalog, MSG_SHORTCUT_SAVE_AS, "A"         );
  895.     NewMenu[7].nm_Label   = GetCatalogStr(li.li_Catalog, MSG_QUIT            , "Quit"      );
  896.     NewMenu[7].nm_CommKey = GetCatalogStr(li.li_Catalog, MSG_SHORTCUT_QUIT   , "Q"         );
  897.     NewMenu[8].nm_Label   = GetCatalogStr(li.li_Catalog, MSG_HELP            , "Help"      );
  898.     NewMenu[9].nm_Label   = GetCatalogStr(li.li_Catalog, MSG_ABOUT2          , "About..."  );
  899.     SpeedGadget.ng_GadgetText = GetCatalogStr(li.li_Catalog, MSG_MESSAGE_DELAY,"Message Delay:");
  900.  
  901.     // we run in English if there is a locale problem
  902.  
  903.     resettime();
  904.  
  905.     if (!(GfxBase = (struct GfxBase *) OpenLibrary("graphics.library", 39L)))
  906.     {   DisplayAlert(AT_Recovery, "\0\20\20Saga: Can't open graphics.library V39+!\0", 24);
  907.     cleanexit(EXIT_FAILURE);
  908.     }
  909.     if (!(GadToolsBase = (struct GfxBase *) OpenLibrary("gadtools.library", 0L)))
  910.     {   DisplayAlert(AT_Recovery, "\0\20\20Saga: Can't open gadtools.library!\0", 24);
  911.     cleanexit(EXIT_FAILURE);
  912.     }
  913.     if (!(ASLBase = (struct ASLBase *) OpenLibrary("asl.library", 38L)))
  914.     {   DisplayAlert(AT_Recovery, "\0\20\20Saga: Can't open ASL.library V38+!\0", 24);
  915.     cleanexit(EXIT_FAILURE);
  916.     }
  917.  
  918.     hero[BEOWULF  ].control = HUMAN;
  919.     hero[BRUNHILD ].control = NONE;
  920.     hero[EGIL     ].control = NONE;
  921.     hero[RAGNAR   ].control = AMIGA;
  922.     hero[SIEGFRIED].control = NONE;
  923.     hero[STARKAD  ].control = NONE;
  924.  
  925.     ok = FALSE;
  926.     if (FileHandle = Open("PROGDIR:Saga.config", MODE_OLDFILE))
  927.     {   if (Read(FileHandle, IOBuffer, 21) == 21)
  928.         {   ok = TRUE;
  929.             for (whichhero = 0; whichhero <= HEROES; whichhero++)
  930.             {   hero[whichhero].control = (SLONG) ((SBYTE) IOBuffer[whichhero]);
  931.             }
  932.             DisplayID     = (ULONG) (  (IOBuffer[ 6] * 16777216)
  933.                                      + (IOBuffer[ 7] *    65536)
  934.                                      + (IOBuffer[ 8] *      256)
  935.                                      +  IOBuffer[ 9]            );
  936.             DisplayWidth  = (ULONG) (  (IOBuffer[10] * 16777216)
  937.                                      + (IOBuffer[11] *    65536)
  938.                                      + (IOBuffer[12] *      256)
  939.                                      +  IOBuffer[13]            );
  940.             DisplayHeight = (ULONG) (  (IOBuffer[14] * 16777216)
  941.                                      + (IOBuffer[15] *    65536)
  942.                                      + (IOBuffer[16] *      256)
  943.                                      +  IOBuffer[17]            );
  944.             DisplayDepth  = (UWORD) (  (IOBuffer[18] *      256)
  945.                                      +  IOBuffer[19]            );
  946.             speed =         (WORD)      IOBuffer[20];
  947.         }
  948.         Close(FileHandle);
  949.         // FileHandle = NULL;
  950.     }
  951.  
  952.     /* argument parsing */
  953.  
  954.     if (argc) /* started from CLI */
  955.     {   if (!(ArgsPtr = ReadArgs
  956.         (   "FILE",
  957.             (LONG *) args,
  958.             NULL
  959.         )))
  960.         {   strcpy(smrstring, GetCatalogStr(li.li_Catalog, MSG_USAGE, "Usage"));
  961.             strcat(smrstring, ": %s [[FILE=]<savedgame>]\n");
  962.             Printf(smrstring, argv[0]);
  963.             cleanexit(EXIT_FAILURE);
  964.         }
  965.         if (args[0])
  966.         {   strcpy(pathname, args[0]);
  967.             cliload = TRUE;
  968.     }   }
  969.  
  970.     strcpy(smrstring, "Saga: ");
  971.     strcat(smrstring, GetCatalogStr(li.li_Catalog, MSG_S_M_R, "Screen Mode Requester"));
  972.  
  973.     if (!ok)
  974.     {   if (!(smr = (struct ScreenModeRequester *) AllocAslRequestTags
  975.         (   ASL_ScreenModeRequest,
  976.             ASLSM_TitleText,            smrstring,
  977.             ASLSM_InitialDisplayID,     HIRES_KEY | PAL_MONITOR_ID | LACE,
  978.             ASLSM_InitialDisplayWidth,  SCREENXPIXEL,
  979.             ASLSM_InitialDisplayHeight, SCREENYPIXEL,
  980.             ASLSM_InitialDisplayDepth,  DEPTH,
  981.             ASLSM_DoWidth,              TRUE,
  982.             ASLSM_DoHeight,             TRUE,
  983.             ASLSM_DoDepth,              TRUE,
  984.             ASLSM_MinWidth,             SCREENXPIXEL,
  985.             ASLSM_MinHeight,            SCREENYPIXEL,
  986.             ASLSM_MinDepth,             DEPTH,
  987.             TAG_DONE
  988.         )))
  989.         {   DisplayAlert(AT_Recovery, "\0\20\20Saga: Can't create ASL screen mode request!\0", 24);
  990.             cleanexit(EXIT_FAILURE);
  991.         }
  992.         if (AslRequest(smr, 0L))
  993.         {   DisplayID     = smr->sm_DisplayID;
  994.             DisplayWidth  = smr->sm_DisplayWidth;
  995.             DisplayHeight = smr->sm_DisplayHeight;
  996.             DisplayDepth  = smr->sm_DisplayDepth;
  997.         }
  998.         FreeAslRequest(smr);
  999.     }
  1000.  
  1001.     ScreenPtr = (struct Screen *) OpenScreenTags
  1002.     (   NULL,
  1003.         SA_Width,       DisplayWidth,
  1004.         SA_Height,      DisplayHeight,
  1005.         SA_Depth,       DisplayDepth,
  1006.         SA_DisplayID,   DisplayID,
  1007.         SA_Title,       TITLEBAR,
  1008.         SA_Font,        &Topaz8,
  1009.         SA_PubName,     "SAGA",
  1010.         SA_Colors32,    table1,
  1011.         SA_Pens,        Pens,
  1012.         SA_Interleaved, TRUE,
  1013.         TAG_DONE
  1014.     );
  1015.     if (!ScreenPtr)
  1016.     {   DisplayAlert(AT_Recovery, "\0\20\20Saga: Can't open screen!\0", 24);
  1017.         cleanexit(EXIT_FAILURE);
  1018.     }
  1019.     PubScreenStatus(ScreenPtr, NULL); // take the screen public
  1020.  
  1021.     for (whichcountry = 36; whichcountry <= 65; whichcountry++)
  1022.     {   SetRGB32(&ScreenPtr->ViewPort, 8 + whichcountry, 0x00000000, 0x00000000, 0x99999999);
  1023.     }
  1024.     LoadRGB32(&(ScreenPtr->ViewPort), table2);
  1025.  
  1026.     /* GadTools */
  1027.     if (!(VisualInfoPtr = (APTR) GetVisualInfo(ScreenPtr, TAG_DONE)))
  1028.     {   DisplayAlert(AT_Recovery, "\0\20\20Saga: Can't get GadTools visual info!\0", 24);
  1029.     cleanexit(EXIT_FAILURE);
  1030.     }
  1031.     for (whichhero = 0; whichhero <= HEROES; whichhero++)
  1032.     {   CycleGadget[whichhero].ng_VisualInfo = VisualInfoPtr;
  1033.     }
  1034.     SpeedGadget.ng_VisualInfo = VisualInfoPtr;
  1035.  
  1036.     if (!(MenuPtr = (struct Menu *) CreateMenus(NewMenu, TAG_DONE)))
  1037.     {   DisplayAlert(AT_Recovery, "\0\20\20Saga: Can't create menus!\0", 24);
  1038.         cleanexit(EXIT_FAILURE);
  1039.     }
  1040.     if (!(LayoutMenus(MenuPtr, VisualInfoPtr, TAG_DONE)))
  1041.     {   DisplayAlert(AT_Recovery, "\0\20\20Saga: Can't lay out menus!\0", 24);
  1042.     cleanexit(EXIT_FAILURE);
  1043.     }
  1044.     if (!(PrevGadgetPtr = (struct Gadget *) CreateContext(&GListPtr)))
  1045.     {   DisplayAlert(AT_Recovery, "\0\20\20Saga: Can't create GadTools context!\0", 24);
  1046.     cleanexit(EXIT_FAILURE);
  1047.     }
  1048.  
  1049.     for (whichhero = 0; whichhero <= HEROES; whichhero++)
  1050.     {   CycleGadgetPtr[whichhero] = PrevGadgetPtr = (struct Gadget *) CreateGadget
  1051.         (   CYCLE_KIND,
  1052.             PrevGadgetPtr,
  1053.             &CycleGadget[whichhero],
  1054.             GTCY_Labels, CycleOptions,
  1055.             GTCY_Active, hero[whichhero].control,
  1056.             TAG_DONE
  1057.     );
  1058.     }
  1059.     SpeedGadgetPtr = PrevGadgetPtr = (struct Gadget *) CreateGadget
  1060.     (   SLIDER_KIND,
  1061.         PrevGadgetPtr,
  1062.         &SpeedGadget,
  1063.         GA_RelVerify,  TRUE,
  1064.         GTSL_Min,      0,
  1065.         GTSL_Max,      4,
  1066.         GTSL_Level,    speed,
  1067.         GT_Underscore, '_',
  1068.         TAG_DONE
  1069.     );
  1070.  
  1071.     /* main window */
  1072.     if (!(MainWindowPtr = (struct Window *) OpenWindowTags(NULL,
  1073.         WA_Left,                0,
  1074.         WA_Top,                 11,
  1075.         WA_Width,               640,
  1076.         WA_Height,              501,
  1077.         WA_IDCMP,               IDCMP_RAWKEY
  1078.                               | IDCMP_VANILLAKEY
  1079.                               | IDCMP_MOUSEBUTTONS
  1080.                               | IDCMP_INTUITICKS
  1081.                               | IDCMP_CLOSEWINDOW
  1082.                               | IDCMP_REFRESHWINDOW
  1083.                               | IDCMP_MENUPICK
  1084.                               | IDCMP_MENUVERIFY
  1085.                               | CYCLEIDCMP,
  1086.         WA_Flags,               WFLG_BORDERLESS,
  1087.         WA_Gadgets,             GListPtr,
  1088.     WA_CustomScreen,    ScreenPtr,
  1089.     WA_Activate,        TRUE,
  1090.     TAG_DONE)))
  1091.         {   DisplayAlert(AT_Recovery, "\0\20\20Saga: Can't open window!\0", 24);
  1092.             cleanexit(EXIT_FAILURE);
  1093.     }
  1094.  
  1095.     /* redirection of AmigaDOS system requesters */
  1096.     OldWindowPtr = ProcessPtr->pr_WindowPtr;
  1097.     ProcessPtr->pr_WindowPtr = (APTR) MainWindowPtr;
  1098.  
  1099.     if (!(ASLRqPtr = AllocAslRequestTags(ASL_FileRequest, ASL_Pattern, "#?.saga", ASL_Window, MainWindowPtr, TAG_DONE)))
  1100.     {   DisplayAlert(AT_Recovery, "\0\20\20Saga: Can't create ASL file request!\0", 24);
  1101.         cleanexit(EXIT_FAILURE);
  1102.     }
  1103.  
  1104.     SetMenuStrip(MainWindowPtr, MenuPtr);
  1105.     createcounters();
  1106.  
  1107.     while (1)
  1108.     {   titlescreen();
  1109.         if (!loaded)
  1110.         {   newgame();
  1111.         }
  1112.         gameloop();
  1113. }   }
  1114.  
  1115. MODULE void gameloop(void)
  1116. {   SLONG countertype,
  1117.           fastest,
  1118.           strongest,
  1119.           strongestjarl,
  1120.           result,
  1121.           whichhero,
  1122.           whichjarl,
  1123.           whichcountry,
  1124.           whichmonster,
  1125.           whichtreasure,
  1126.           whichsord;
  1127.     FLAG  transfer;
  1128.  
  1129.     do
  1130.     {   strcpy(titlestring, TITLEBAR);
  1131.         strcat(titlestring, ": ");
  1132.         strcat(titlestring, GetCatalogStr(li.li_Catalog, MSG_TURN, "Turn"));
  1133.         strcat(titlestring, " ");
  1134.         stcl_d(numberstring, turn);
  1135.         strcat(titlestring, numberstring);
  1136.         strcat(titlestring, " ");
  1137.         strcat(titlestring, GetCatalogStr(li.li_Catalog, MSG_OF, "of"));
  1138.         strcat(titlestring, " ");
  1139.         stcl_d(numberstring, TURNS);
  1140.         strcat(titlestring, numberstring);
  1141.         SetWindowTitles(MainWindowPtr, (UBYTE *) -1, titlestring); // this is not copied, it is a pointer
  1142.  
  1143.         strcpy(saystring, GetCatalogStr(li.li_Catalog, MSG_TURN, "Turn"));
  1144.         strcat(saystring, " ");
  1145.         stcl_d(numberstring, turn);
  1146.         strcat(saystring, numberstring);
  1147.         strcat(saystring, " ");
  1148.         strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_OF, "of"));
  1149.         strcat(saystring, " ");
  1150.         stcl_d(numberstring, TURNS);
  1151.         strcat(saystring, numberstring);
  1152.         strcat(saystring, "...");
  1153.         say(LOWER);
  1154.  
  1155.          OnMenu(MainWindowPtr, FULLMENUNUM(MN_PROJECT, IN_NEW,    NOSUB));
  1156.          OnMenu(MainWindowPtr, FULLMENUNUM(MN_PROJECT, IN_SAVE,   NOSUB));
  1157.          OnMenu(MainWindowPtr, FULLMENUNUM(MN_PROJECT, IN_SAVEAS, NOSUB));
  1158.         result = getevent(KEYBOARD, NULL);
  1159.         if (result == -4)
  1160.         {   for (whichhero = 0; whichhero <= HEROES; whichhero++)
  1161.             {   hero[whichhero].alive    = FALSE;
  1162.                 hero[whichhero].verydead = TRUE;
  1163.             }
  1164.             gameover = TRUE;
  1165.         }
  1166.         OffMenu(MainWindowPtr, FULLMENUNUM(MN_PROJECT, IN_NEW,    NOSUB));
  1167.         OffMenu(MainWindowPtr, FULLMENUNUM(MN_PROJECT, IN_SAVE,   NOSUB));
  1168.         OffMenu(MainWindowPtr, FULLMENUNUM(MN_PROJECT, IN_SAVEAS, NOSUB));
  1169.  
  1170.         if (!gameover)
  1171.         {
  1172.         for (whichhero = 0; whichhero <= HEROES; whichhero++)
  1173.         {   if (!hero[whichhero].alive && !hero[whichhero].verydead)
  1174.             {   transfer = FALSE;
  1175.                 for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
  1176.                 {   if (jarl[whichjarl].alive && jarl[whichjarl].hero == whichhero)
  1177.                     {   transfer = TRUE;
  1178.                         break; // for speed
  1179.                 }   }
  1180.  
  1181.                 if (hero[whichhero].control == AMIGA)
  1182.                 {   if (transfer)
  1183.                     {   strongest = fastest = 0;
  1184.                         for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
  1185.                         {   if
  1186.                             (   jarl[whichjarl].alive
  1187.                              && jarl[whichjarl].hero == whichhero
  1188.                             )
  1189.                             {   if (jarl[whichjarl].strength > strongest)
  1190.                                 {   strongest     = jarl[whichjarl].strength;
  1191.                                     fastest       = jarl[whichjarl].moves;
  1192.                                     strongestjarl = whichjarl;
  1193.                                 } elif (jarl[whichjarl].strength == strongest)
  1194.                                 {   if (jarl[whichjarl].moves > fastest)
  1195.                                     {   strongest     = jarl[whichjarl].strength;
  1196.                                         fastest       = jarl[whichjarl].moves;
  1197.                                         strongestjarl = whichjarl;
  1198.                         }   }   }   }
  1199.                         promote(whichhero, strongestjarl);
  1200.                         strcpy(saystring, GetCatalogStr(li.li_Catalog, MSG_DEAD_HERO, "Dead hero"));
  1201.                         strcat(saystring, " ");
  1202.                         strcat(saystring, hero[whichhero].name);
  1203.                         strcat(saystring, " ");
  1204.                         strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_PROMOTES_JARL, "promotes jarl"));
  1205.                         strcat(saystring, " ");
  1206.                         strcat(saystring, jarl[strongestjarl].name);
  1207.                         strcat(saystring, " (");
  1208.                         stcl_d(numberstring, jarl[strongestjarl].strength);
  1209.                         strcat(saystring, numberstring);
  1210.                         strcat(saystring, "-");
  1211.                         stcl_d(numberstring, jarl[strongestjarl].moves);
  1212.                         strcat(saystring, numberstring);
  1213.                         strcat(saystring, ").");
  1214.                         say(LOWER);
  1215.                         anykey();
  1216.                     } else
  1217.                     {   withdraw(whichhero);
  1218.                         strcpy(saystring, GetCatalogStr(li.li_Catalog, MSG_DEAD_HERO, "Dead hero"));
  1219.                         strcat(saystring, " ");
  1220.                         strcat(saystring, hero[whichhero].name);
  1221.                         strcat(saystring, " ");
  1222.                         strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_WITHDRAWS_FROM_PLAY, "withdraws from play"));
  1223.                         strcat(saystring, ".");
  1224.                         say(LOWER);
  1225.                         anykey();
  1226.                 }   }
  1227.                 elif (hero[whichhero].control == HUMAN)
  1228.                 {   strcpy(saystring, GetCatalogStr(li.li_Catalog, MSG_DEAD_HERO, "Dead hero"));
  1229.                     strcat(saystring, " ");
  1230.                     strcat(saystring, hero[whichhero].name);
  1231.                     strcat(saystring, ", (");
  1232.                     strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_CHAR_WITHDRAW, "W"));
  1233.                     strcat(saystring, ")");
  1234.                     strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_UNCHAR_WITHDRAW, "ithdraw"));
  1235.                     strcat(saystring, "/(");
  1236.                     strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_CHAR_RESTART, "R"));
  1237.                     strcat(saystring, ")");
  1238.                     strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_UNCHAR_RESTART, "estart"));
  1239.                     if (transfer)
  1240.                     {   strcat(saystring, "/(");
  1241.                         strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_CHAR_TRANSFER, "T"));
  1242.                         strcat(saystring, ")");
  1243.                         strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_UNCHAR_TRANSFER, "ransfer"));
  1244.                         strcat(saystring, "?");
  1245.                         say(LOWER);
  1246.                         do
  1247.                         {   result = getevent(KEYBOARD, NULL);
  1248.                         } while (result != onekey[ONEKEY_WITHDRAW] && result != onekey[ONEKEY_RESTART] && result != onekey[ONEKEY_TRANSFER]);
  1249.                         if (result == onekey[ONEKEY_TRANSFER])
  1250.                         {   strcpy(saystring, GetCatalogStr(li.li_Catalog, MSG_DEAD_HERO, "Dead hero"));
  1251.                             strcat(saystring, " ");
  1252.                             strcat(saystring, hero[whichhero].name);
  1253.                             strcat(saystring, ", ");
  1254.                             strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_S_W_J_T_P, "select which jarl to promote"));
  1255.                             strcat(saystring, "?");
  1256.                             say(LOWER);
  1257.                             do
  1258.                             {   whichjarl = getevent(COUNTER, &countertype);
  1259.                             } while
  1260.                             (   whichjarl < 0
  1261.                              || countertype != JARL
  1262.                              || jarl[whichjarl].hero != whichhero
  1263.                             );
  1264.                             promote(whichhero, whichjarl);
  1265.                     }   }
  1266.                     else
  1267.                     {   strcat(saystring, "?");
  1268.                         say(LOWER);
  1269.                         do
  1270.                         {   result = getevent(KEYBOARD, NULL);
  1271.                         } while (result != onekey[ONEKEY_WITHDRAW] && result != onekey[ONEKEY_RESTART]);
  1272.                     }
  1273.                     if (result == onekey[ONEKEY_WITHDRAW])
  1274.                     {   withdraw(whichhero);
  1275.                     } elif (result == onekey[ONEKEY_RESTART])
  1276.                     {   newhero(whichhero, FALSE);
  1277.         }   }   }   }
  1278.  
  1279.         phase1(); // movement
  1280.         phase2(); // combat
  1281.         phase3(); // kingdoms
  1282.  
  1283.         /* "4. PLACE MONSTERS. A number of monsters equal to the number
  1284.         of heroes in play are randomly placed face up by rolling two dice
  1285.         and placing the monster in the area indicated. (This is done every
  1286.         turn until all counters are used. "Dead" monsters may not be
  1287.         reused." */
  1288.  
  1289.         place_monsters(); // phase 4
  1290.  
  1291.         /* "5. PLACE jarls. A number of jarls equal to the number of
  1292.         heroes in play are randomly placed face up by rolling two dice
  1293.         and placing the jarl in the area indicated. (This is done every
  1294.         turn until all counters are used. "Dead" jarls may not be
  1295.         reused." */
  1296.  
  1297.         place_jarls();    // phase 5
  1298.  
  1299.         refreshcounters();
  1300.  
  1301.         /* 6. MARK TURN. One turn is marked off. */
  1302.  
  1303.         turn++;
  1304.         }
  1305.     } while (turn <= TURNS && !gameover);
  1306.  
  1307.     /* "At the end of the 20th turn the game is over and players total
  1308.     their glory to determine who has won. The turn should be marked off on
  1309.     each player's record sheet." */
  1310.  
  1311.     for (whichhero = 0; whichhero <= HEROES; whichhero++)
  1312.     {   remove_hero(whichhero, FALSE);
  1313.     }
  1314.     for (whichjarl = 0; whichjarl <= JARL; whichjarl++)
  1315.     {   remove_jarl(whichjarl, FALSE);
  1316.     }
  1317.     for (whichmonster = 0; whichmonster <= MONSTERS; whichmonster++)
  1318.     {   remove_monster(whichmonster, FALSE);
  1319.     }
  1320.     for (whichtreasure = 0; whichtreasure <= TREASURES; whichtreasure++)
  1321.     {   remove_treasure(whichtreasure, FALSE);
  1322.     }
  1323.     for (whichsord = 0; whichsord <= SORDS; whichsord++)
  1324.     {   remove_sord(whichsord, FALSE);
  1325.     }
  1326.     refreshcounters();
  1327.     for (whichcountry = 0; whichcountry <= 65; whichcountry++)
  1328.     {   world[whichcountry].hero = -1;
  1329.     }
  1330.  
  1331.     if (!gameover)
  1332.     {   SetAPen(MainWindowPtr->RPort, BLACK);
  1333.         RectFill(MainWindowPtr->RPort, 0, 0, SCREENXPIXEL, SCREENYPIXEL);
  1334.  
  1335.         strcpy(saystring, GetCatalogStr(li.li_Catalog, MSG_GAME_OVER, "Game over"));
  1336.         strcat(saystring, "!");
  1337.         say(LOWER);                          
  1338.  
  1339.         SetDrMd(MainWindowPtr->RPort, JAM1);
  1340.         for (whichhero = 0; whichhero <= HEROES; whichhero++)
  1341.         {   if (hero[whichhero].control != NONE)
  1342.             {   hero[whichhero].glory += hero[whichhero].wealth / 10;
  1343.                 hero[whichhero].glory += hero[whichhero].luck   /  3;
  1344.                 if
  1345.                 (   treasure[BROSUNGNECKLACE].possessortype == HERO
  1346.                  && treasure[BROSUNGNECKLACE].possessor == whichhero
  1347.                 )
  1348.                 {   hero[whichhero].wealth += 20;
  1349.                 }
  1350.                 for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
  1351.                 {   if (jarl[whichjarl].alive && jarl[whichjarl].hero == whichhero)
  1352.                     {   hero[whichhero].glory += jarl[whichjarl].strength / 2;
  1353.                         if
  1354.                         (   treasure[BROSUNGNECKLACE].possessortype == JARL
  1355.                          && treasure[BROSUNGNECKLACE].possessor == whichjarl
  1356.                         )
  1357.                         {   hero[whichhero].wealth += 20;
  1358.             }   }   }   }
  1359.             if (hero[whichhero].control == NONE)
  1360.             {   SetAPen(MainWindowPtr->RPort, MEDIUMGREY);
  1361.             } elif (hero[whichhero].glory >= 15)
  1362.             {   SetAPen(MainWindowPtr->RPort, GREEN);
  1363.             } else
  1364.             {   SetAPen(MainWindowPtr->RPort, RED);
  1365.             }
  1366.             RectFill(MainWindowPtr->RPort, 320 - 70, 200 + (whichhero * SCOREDISTANCE), 320 + 70, 200 + 11 + (whichhero * SCOREDISTANCE));
  1367.         
  1368.             SetAPen(MainWindowPtr->RPort, BLACK);
  1369.             Move(MainWindowPtr->RPort, 320 - 70 + 4, 200 + 8 + (whichhero * SCOREDISTANCE));
  1370.             Text(MainWindowPtr->RPort, hero[whichhero].name, strlen(hero[whichhero].name));
  1371.         
  1372.             if (hero[whichhero].control == NONE)
  1373.             {   strcpy(numberstring, "-");
  1374.             } else
  1375.             {   stcl_d(numberstring, hero[whichhero].glory);
  1376.                 Move(MainWindowPtr->RPort, 320 + 70 - (8 * 4) - 4 + (8 * (4 - strlen(numberstring))), 200 + 8 + (whichhero * SCOREDISTANCE));
  1377.                 Text(MainWindowPtr->RPort, numberstring, strlen(numberstring));
  1378.         }   }
  1379.         SetAPen(MainWindowPtr->RPort, BLACK);
  1380.         Move(MainWindowPtr->RPort, 340, 200);
  1381.         Draw(MainWindowPtr->RPort, 340, 200 + ((HEROES + 1) * SCOREDISTANCE));
  1382.         
  1383.         anykey();
  1384. }   }    
  1385.  
  1386. MODULE void callforaid(SLONG passedtype, SLONG passed)
  1387. {   SLONG passedhero, passedwhere, whichjarl;
  1388.  
  1389.     if (passedtype == HERO)
  1390.     {   passedhero = passed;
  1391.         passedwhere = hero[passed].where;
  1392.     } else
  1393.     {   // assert(passedtype == JARL);
  1394.         // assert(jarl[passed].hero != -1);
  1395.         passedhero = jarl[passed].hero;
  1396.         passedwhere = jarl[passed].where;
  1397.     }
  1398.  
  1399.     if (passedtype == JARL && hero[passedhero].where == passedwhere)
  1400.     {   hero[passedhero].defending = TRUE;
  1401.         select_hero(passedhero);
  1402.     }
  1403.  
  1404.     for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
  1405.     {   if
  1406.         (   jarl[whichjarl].hero == passedhero
  1407.          && jarl[whichjarl].where == passedwhere
  1408.          && !jarl[whichjarl].defending
  1409.         )
  1410.         {   jarl[whichjarl].defending = TRUE;
  1411.             select_jarl(whichjarl);
  1412. }   }   }
  1413.  
  1414. /*
  1415.         assert(hero[passedhero].control == HUMAN);
  1416.         
  1417.         strcpy(saystring, GetCatalogStr(li.li_Catalog, MSG_DEFENDING, "Defending"));
  1418.         saywho(passedtype, passed, TRUE, FALSE);
  1419.         strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_CALL_FOR_AID, "call for aid"));
  1420.         strcat(saystring, "?");
  1421.         say(LOWER);
  1422.     
  1423.         while (1)
  1424.         {   counter = getevent(COUNTER, &countertype);
  1425.             if (countertype == HERO && counter == passedhero && passedtype == JARL && hero[counter].where == passedwhere)
  1426.             {   if (hero[counter].defending)
  1427.                 {   deselect_hero(counter, TRUE);
  1428.                     hero[counter].defending = FALSE;
  1429.                 } else
  1430.                 {   select_hero(counter);
  1431.                     hero[counter].defending = TRUE;
  1432.             }   }
  1433.             elif (countertype == JARL && jarl[counter].hero == passedhero && (passedtype == HERO || passed != counter) && jarl[counter].where == passedwhere)
  1434.             {   if (jarl[counter].defending)
  1435.                 {   deselect_jarl(counter);
  1436.                     jarl[counter].defending = FALSE;
  1437.                 } else
  1438.                 {   select_jarl(counter);
  1439.                     jarl[counter].defending = TRUE;
  1440.             }   }
  1441.             elif (counter == -2) // backspace
  1442.             {   for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
  1443.                 {   if
  1444.                     (   jarl[whichjarl].defending
  1445.                      && (passedtype == HERO || passed != whichjarl)
  1446.                     )
  1447.                     {   jarl[whichjarl].defending = FALSE;
  1448.                         deselect_jarl(whichjarl);
  1449.                 }   }
  1450.                 if (passedtype == JARL && hero[passedhero].defending)
  1451.                 {   hero[passedhero].defending = FALSE;
  1452.                     deselect_hero(passedhero, TRUE);
  1453.             }   }
  1454.             elif (counter <= -3)
  1455.             {   return;
  1456. }   }   }   }
  1457. */
  1458.  
  1459. MODULE void dobattle(SLONG defendtype, SLONG defender, SLONG attackhero)
  1460. {   SLONG decision,
  1461.           result,
  1462.           attackstrength = 0,
  1463.           attackluck     = 0,
  1464.           attacktype,
  1465.           attacker,
  1466.           defendstrength = 0,
  1467.           defendluck     = 0,
  1468.           defendhero,
  1469.           whichhero,
  1470.           whichjarl,
  1471.           whichsord;
  1472.  
  1473.     /* defendtype: type of defender, one of HERO, JARL, MONSTER or KINGDOM.
  1474.        defender: ordinal number of defender. */
  1475.  
  1476.     if (defendtype == HERO)
  1477.     {   defendhero = defender;
  1478.         hero[defender].defending = TRUE;
  1479.         select_hero(defender);
  1480.         callforaid(HERO, defender);
  1481.     } elif (defendtype == JARL)
  1482.     {   defendhero = jarl[defender].hero;
  1483.         jarl[defender].defending = TRUE;
  1484.         select_jarl(defender);
  1485.         if (defendhero != -1)
  1486.         {   callforaid(JARL, defender);
  1487.     }   }
  1488.     elif (defendtype == MONSTER)
  1489.     {   defendstrength = monster[defender].strength;
  1490.         defendhero = -1;
  1491.     } else
  1492.     {   // assert(defendtype == KINGDOM);
  1493.         defendstrength = world[defender].tax;
  1494.         defendhero = -1; // even if it already has a king it makes no difference to the combat
  1495.     }
  1496.  
  1497.     // "II. ROLL FOR DROW, WITCH, OR GHOST MAGIC SPELLS (IF APPLICABLE)."
  1498.  
  1499.     if (defendtype == MONSTER)
  1500.     {   if (monster[defender].species == GHOST)
  1501.         {   decision = d6();
  1502.             if (decision <= 3)
  1503.             {   cast(defender, decision);
  1504.         }   }
  1505.         elif (monster[defender].species == DROW)
  1506.         {   cast(defender, d6());
  1507.         } elif (monster[defender].species == WITCH)
  1508.         {   cast(defender, d6());
  1509.             if (attackersleft())
  1510.             {   cast(defender, d6());
  1511.     }   }   }
  1512.  
  1513.     if (!attackersleft())
  1514.     {   // no attackers, abort combat
  1515.         return;
  1516.     }
  1517.  
  1518.     for (whichhero = 0; whichhero <= HEROES; whichhero++)
  1519.     {   if (hero[whichhero].attacking)
  1520.         {   attackstrength += hero[whichhero].strength;
  1521.         } elif (hero[whichhero].defending)
  1522.         {   defendstrength += hero[whichhero].strength;
  1523.     }   }
  1524.     for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
  1525.     {   if (jarl[whichjarl].attacking)
  1526.         {   attackstrength += jarl[whichjarl].strength;
  1527.         } elif (jarl[whichjarl].defending)
  1528.         {   defendstrength += jarl[whichjarl].strength;
  1529.     }   }
  1530.  
  1531.     for (whichhero = 0; whichhero <= HEROES; whichhero++)
  1532.     {   if (hero[whichhero].attacking && hero[whichhero].hagall)
  1533.         {   attackstrength--;
  1534.         } elif (hero[whichhero].defending && hero[whichhero].hagall)
  1535.         {   defendstrength--;
  1536.     }   }
  1537.     for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
  1538.     {   if (jarl[whichjarl].attacking && jarl[whichjarl].hagall)
  1539.         {   attackstrength--;
  1540.         } elif (jarl[whichjarl].defending && jarl[whichjarl].hagall)
  1541.         {   defendstrength--;
  1542.     }   }
  1543.     if (defendtype == MONSTER && monster[defender].hagall)
  1544.     {   defendstrength--;
  1545.     }
  1546.  
  1547.     /* "III. MODIFY THE DIE ROLL WITH LUCK. Before the die is rolled,
  1548.     heroes who are involved in the battle (or who have jarls involved in
  1549.     the battle) may modify the die roll up or down one with each point of
  1550.     luck expended before the die is rolled. If there are two or more
  1551.     heroes involved in the battle they should each write how much luck
  1552.     they are using to modify the die roll and how before revealing the
  1553.     amounts simultaneously." */
  1554.  
  1555.     if (hero[attackhero].luck >= 1)
  1556.     {   if (hero[attackhero].control == HUMAN)
  1557.         {   strcpy(saystring, GetCatalogStr(li.li_Catalog, MSG_ATTACKING, "Attacking"));
  1558.             saywho(HERO, attackhero, FALSE, TRUE);
  1559.             strcat(saystring, ", ");
  1560.             strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_USE_LUCK, "use luck"));
  1561.             strcat(saystring, " (0-");
  1562.             if (hero[attackhero].luck >= 9)
  1563.             {   strcat(saystring, "9");
  1564.             } else
  1565.             {   stcl_d(numberstring, hero[attackhero].luck);
  1566.                 strcat(saystring, numberstring);
  1567.             }
  1568.             strcat(saystring, ")?");
  1569.             say(LOWER);
  1570.             attackstrength += getluck(attackhero);
  1571.         } else
  1572.         {   // assert(hero[attackhero].control == AMIGA);
  1573.             attackluck = 0;
  1574.     }   }
  1575.  
  1576.     if (defendhero != -1)
  1577.     {   if (hero[defendhero].control == HUMAN)
  1578.         {   if (hero[defendhero].luck >= 1)
  1579.             {   strcpy(saystring, GetCatalogStr(li.li_Catalog, MSG_DEFENDING, "Defending"));
  1580.                 saywho(defendtype, defender, FALSE, TRUE);
  1581.                 strcat(saystring, ", ");
  1582.                 strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_USE_LUCK, "use luck"));
  1583.                 strcat(saystring, " (0-");
  1584.                 if (hero[defendhero].luck >= 9)
  1585.                 {   strcat(saystring, "9");
  1586.                 } else
  1587.                 {   stcl_d(numberstring, hero[defendhero].luck);
  1588.                     strcat(saystring, numberstring);
  1589.                 }
  1590.                 strcat(saystring, ")?");
  1591.                 say(LOWER);
  1592.                 defendstrength += getluck(defendhero);
  1593.         }   }
  1594.         else
  1595.         {   // assert(hero[defendhero].control == AMIGA);
  1596.             defendluck = 0;
  1597.     }   }
  1598.  
  1599. /*  if (hero[attackhero].control == AMIGA && attackluck > 0)
  1600.     {   strcpy(saystring, GetCatalogStr(li.li_Catalog, MSG_ATTACKING, "Attacking"));
  1601.         saywho(HERO, attackhero, FALSE, TRUE);
  1602.         strcat(saystring, " ");
  1603.         strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_USED, "used"));
  1604.         strcat(saystring, " ");
  1605.         stcl_d(numberstring, attackluck);
  1606.         strcat(saystring, numberstring);
  1607.         strcat(saystring, " ");
  1608.         strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_LUCK2, "luck"));
  1609.         strcat(saystring, ".");
  1610.         say(LOWER);
  1611.         anykey();
  1612.     }
  1613.     if (defendhero != -1)
  1614.     {   if (hero[defendhero].control == AMIGA && defendluck > 0)
  1615.         {   strcpy(saystring, GetCatalogStr(li.li_Catalog, MSG_DEFENDING, "Defending"));
  1616.             saywho(HERO, defendhero, FALSE, TRUE);
  1617.             strcat(saystring, ", ");
  1618.             strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_USED, "used"));
  1619.             strcat(saystring, " ");
  1620.             stcl_d(numberstring, defendluck);
  1621.             strcat(saystring, numberstring);
  1622.             strcat(saystring, " ");
  1623.             strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_LUCK2, "luck"));
  1624.             strcat(saystring, ".");
  1625.             say(LOWER);
  1626.             anykey();
  1627.     }   } */
  1628.  
  1629.     for (whichhero = 0; whichhero <= HEROES; whichhero++)
  1630.     {   if (hero[whichhero].alive && hero[whichhero].rune == OGAL)
  1631.         {   if (hero[whichhero].attacking)
  1632.             {   attackstrength++;
  1633.             } elif (hero[whichhero].defending)
  1634.             {   defendstrength++;
  1635.     }   }   }
  1636.  
  1637.     for (whichsord = 0; whichsord <= SORDS; whichsord++)
  1638.     {   if
  1639.         (   (   sord[whichsord].possessortype == HERO
  1640.              && hero[sord[whichsord].possessor].attacking
  1641.             )
  1642.          || (   sord[whichsord].possessortype == JARL
  1643.              && jarl[sord[whichsord].possessor].attacking
  1644.         )   )
  1645.         {   if (whichsord == BALMUNG || whichsord == HRUNTING)
  1646.             {   attackstrength++;
  1647.             } elif (whichsord == DRAGVENDILL || whichsord == GRAM || whichsord == TYRFING)
  1648.             {   attackstrength += 2;
  1649.             } elif (whichsord == LOVI)
  1650.             {   attackstrength++;
  1651.                 for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
  1652.                 {   if (jarl[whichjarl].defending)
  1653.                     {   attackstrength += 2;
  1654.                         break;
  1655.         }   }   }   }
  1656.         elif
  1657.         (   (   sord[whichsord].possessortype == HERO
  1658.              && hero[sord[whichsord].possessor].defending
  1659.             )
  1660.          || (   sord[whichsord].possessortype == JARL
  1661.              && jarl[sord[whichsord].possessor].defending
  1662.         )   )
  1663.         {   if (whichsord == BALMUNG || whichsord == HRUNTING)
  1664.             {   defendstrength++;
  1665.             } elif (whichsord == DRAGVENDILL || whichsord == GRAM || whichsord == TYRFING)
  1666.             {   defendstrength += 2;
  1667.             } elif (whichsord == LOVI)
  1668.             {   defendstrength++;
  1669.                 for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
  1670.                 {   if (jarl[whichjarl].attacking)
  1671.                     {   defendstrength += 2;
  1672.                         break;
  1673.     }   }   }   }   }
  1674.  
  1675.     if (hero[attackhero].attacking)
  1676.     {   attackstrength += odin_tyr(attackhero, TRUE);
  1677.         if (attackstrength < 0)
  1678.         {   attackstrength = 0;
  1679.     }   }
  1680.     if (defendhero != -1 && hero[defendhero].defending)
  1681.     {   defendstrength += odin_tyr(defendhero, FALSE);
  1682.         if (defendstrength < 0)
  1683.         {   defendstrength = 0;
  1684.     }   }
  1685.  
  1686.     if
  1687.     (   (   sord[BALMUNG].possessortype == HERO
  1688.          && hero[sord[BALMUNG].possessor].attacking
  1689.         )
  1690.      || (   sord[BALMUNG].possessortype == JARL
  1691.          && jarl[sord[BALMUNG].possessor].attacking
  1692.     )   )
  1693.     {   ; // one of the attackers is wielding Balmung
  1694.         // assert(sord[BALMUNG].where == -1);
  1695.     } else
  1696.     {   if
  1697.         (   (   treasure[MAGICSHIRT].possessortype == HERO
  1698.              && hero[treasure[MAGICSHIRT].possessor].defending
  1699.             )
  1700.          || (   treasure[MAGICSHIRT].possessortype == JARL
  1701.              && jarl[treasure[MAGICSHIRT].possessor].defending
  1702.         )   )
  1703.         {   // one of the defenders is wearing the Magic Shirt
  1704.             // assert(treasure[MAGICSHIRT].where == -1);
  1705.  
  1706.             defendstrength++;
  1707.         }
  1708.  
  1709.         if
  1710.         (   (   treasure[MAILCOAT].possessortype == HERO
  1711.              && hero[treasure[MAILCOAT].possessor].defending
  1712.             )
  1713.          || (   treasure[MAILCOAT].possessortype == JARL
  1714.              && jarl[treasure[MAILCOAT].possessor].defending
  1715.         )   )
  1716.         {   // one of the defenders is wearing the Mail Coat
  1717.             // assert(treasure[MAILCOAT].where == -1);
  1718.  
  1719.             defendstrength += 2;
  1720.     }   }
  1721.  
  1722.     /* "V. ROLL ONE DIE AND CHECK THE COMBAT RESULTS TABLE TO DETERMINE
  1723.     THE OUTCOME OF THE BATTLE AFTER ADDING ALL MODIFIERS TO THE DIE ROLL.
  1724.     After all modifications to the combat strengths of both sides have
  1725.     been made, subtract the defender's strength from the attacker's and
  1726.     consult the COMBAT RESULTS TABLE below to determine the results
  1727.     according to a die roll and modifications due to luck." */
  1728.  
  1729. /*
  1730. Printf("Involved in the combat are:\n");
  1731. Printf(" Attackers:\n");
  1732. if (hero[attackhero].attacking)
  1733. {   Printf("  Hero %s!\n", hero[attackhero].name);
  1734. }
  1735. for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
  1736. {   if (jarl[whichjarl].attacking)
  1737.     {   Printf("  Jarl %s!\n", jarl[whichjarl].name);
  1738. }   }
  1739. Printf(" Defenders:\n");
  1740. if (defendhero != -1)
  1741. {   if (hero[defendhero].defending)
  1742.     {   Printf("  Hero %s!\n", hero[defendhero].name);
  1743. }   }
  1744. for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
  1745. {   if (jarl[whichjarl].defending)
  1746.     {   Printf("  Jarl %s!\n", jarl[whichjarl].name);
  1747. }   }
  1748. if (defendhero == -1)
  1749. {   if (defendtype == KINGDOM)
  1750.     {   Printf("  Kingdom %s!\n", world[defender].name);
  1751.     } elif (defendtype == MONSTER)
  1752.     {   Printf("  Monster %s!\n", monster[defender].name);
  1753. }   }
  1754. */
  1755.  
  1756.     result = attackstrength - defendstrength + d6();
  1757.  
  1758.     if (result == 4) // attacker flees
  1759.     {   if (sord[HRUNTING].possessortype == HERO)
  1760.         {   if (hero[sord[HRUNTING].possessor].attacking)
  1761.             {   result = 6; // defender flees
  1762.         }   }
  1763.         elif (sord[HRUNTING].possessortype == JARL)
  1764.         {   if (jarl[sord[HRUNTING].possessor].attacking)
  1765.             {   result = 6; // defender flees
  1766.     }   }   }
  1767.     elif (result == 6) // defender flees
  1768.     {   if (sord[HRUNTING].possessortype == HERO)
  1769.         {   if (hero[sord[HRUNTING].possessor].defending)
  1770.             {   result = 4; // attacker flees
  1771.         }   }
  1772.         elif (sord[HRUNTING].possessortype == JARL)
  1773.         {   if (jarl[sord[HRUNTING].possessor].defending)
  1774.             {   result = 4; // attacker flees
  1775.     }   }   }
  1776.  
  1777.     /* "VI. APPLY THE COMBAT RESULT." */
  1778.  
  1779.     if (hero[attackhero].attacking)
  1780.     {   attacktype = HERO;
  1781.         attacker   = attackhero;
  1782.     } else
  1783.     {   attacktype = JARL; // uses the first jarl found
  1784.         for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
  1785.         {   if (jarl[whichjarl].attacking)
  1786.             {   attacker = whichjarl;
  1787.                 break;
  1788.     }   }   }
  1789.  
  1790.     if (result <= 2) // attackers killed
  1791.     {   if (hero[attackhero].attacking)
  1792.         {   kill(defendtype, defender, defendhero, HERO, attackhero, attackhero);
  1793.         }
  1794.         for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
  1795.         {   if (jarl[whichjarl].attacking)
  1796.             {   kill(defendtype, defender, defendhero, JARL, whichjarl, attackhero);
  1797.     }   }   }
  1798.     elif (result == 3) // attackers wounded
  1799.     {   if (hero[attackhero].attacking)
  1800.         {   wound(defendtype, defender, defendhero, HERO, attackhero, attackhero);
  1801.         }
  1802.         for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
  1803.         {   if (jarl[whichjarl].attacking)
  1804.             {   wound(defendtype, defender, defendhero, JARL, whichjarl, attackhero);
  1805.     }   }   }
  1806.     elif (result == 4) // attackers flee
  1807.     {   if (hero[attackhero].attacking)
  1808.         {   flee(defendtype, defender, defendhero, HERO, attackhero, attackhero);
  1809.         }
  1810.         for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
  1811.         {   if (jarl[whichjarl].attacking)
  1812.             {   flee(defendtype, defender, defendhero, JARL, whichjarl, attackhero);
  1813.     }   }   }
  1814.     elif (result == 5) // no result
  1815.     {   strcpy(saystring, GetCatalogStr(li.li_Catalog, MSG_NO_RESULT, "No result"));
  1816.         strcat(saystring, ".");
  1817.         say(LOWER);
  1818.         anykey();
  1819.     } elif (result == 6) // defenders flee
  1820.     {   if (defendtype == MONSTER || defendtype == KINGDOM)
  1821.         {   flee(attacktype, attacker, attackhero, defendtype, defender, -1);
  1822.         } else
  1823.         {   assert(defendtype == HERO || defendtype == JARL);
  1824.             if (defendhero != -1 && hero[defendhero].defending)
  1825.             {   flee(attacktype, attacker, attackhero, HERO, defendhero, defendhero);
  1826.             }
  1827.             for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
  1828.             {   if (jarl[whichjarl].defending)
  1829.                 {   flee(attacktype, attacker, attackhero, JARL, whichjarl, defendhero);
  1830.     }   }   }   }
  1831.     elif (result == 7) // defenders wounded
  1832.     {   if (defendtype == MONSTER || defendtype == KINGDOM)
  1833.         {   wound(attacktype, attacker, attackhero, defendtype, defender, -1);
  1834.         } else
  1835.         {   assert(defendtype == HERO || defendtype == JARL);
  1836.             if (defendhero != -1 && hero[defendhero].defending)
  1837.             {   wound(attacktype, attacker, attackhero, HERO, defendhero, defendhero);
  1838.             }
  1839.             for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
  1840.             {   if (jarl[whichjarl].defending)
  1841.                 {   wound(attacktype, attacker, attackhero, JARL, whichjarl, defendhero);
  1842.     }   }   }   }
  1843.     else // defenders killed
  1844.     {   // assert(result >= 8);
  1845.         if (defendtype == MONSTER || defendtype == KINGDOM)
  1846.         {   kill(attacktype, attacker, attackhero, defendtype, defender, -1);
  1847.         } else
  1848.         {   assert(defendtype == HERO || defendtype == JARL);
  1849.             if (defendhero != -1 && hero[defendhero].defending)
  1850.             {   kill(attacktype, attacker, attackhero, HERO, defendhero, defendhero);
  1851.             }
  1852.             for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
  1853.             {   if (jarl[whichjarl].defending)
  1854.                 {   kill(attacktype, attacker, attackhero, JARL, whichjarl, defendhero);
  1855.     }   }   }   }
  1856.  
  1857.     if (hero[attackhero].attacking)
  1858.     {   thor(attackhero);
  1859.     }
  1860.     if (defendhero != -1 && hero[defendhero].defending && hero[defendhero].alive)
  1861.     {   thor(defendhero);
  1862.     }
  1863.  
  1864.     if (hero[attackhero].attacking)
  1865.     {   pray(attackhero);
  1866.     }
  1867.     if (defendhero != -1 && hero[defendhero].defending && hero[defendhero].alive)
  1868.     {   pray(defendhero);
  1869.     }
  1870.  
  1871.     if (hero[attackhero].attacking)
  1872.     {   deselect_hero(attackhero, TRUE);
  1873.         hero[attackhero].attacking = FALSE;
  1874.     } elif (hero[defendhero].defending)
  1875.     {   deselect_hero(defendhero, TRUE);
  1876.         hero[defendhero].defending = FALSE;
  1877.     }
  1878.     for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
  1879.     {   if (jarl[whichjarl].attacking)
  1880.         {   deselect_jarl(whichjarl);
  1881.             jarl[whichjarl].attacking   =
  1882.             jarl[whichjarl].recruitable = FALSE;
  1883.         } elif (jarl[whichjarl].defending)
  1884.         {   deselect_jarl(whichjarl);
  1885.             jarl[whichjarl].defending   =
  1886.             jarl[whichjarl].recruitable = FALSE;
  1887. }   }   }
  1888.  
  1889. MODULE void flee(SLONG routertype, SLONG router, SLONG routerhero, SLONG routedtype, SLONG routed, SLONG routedhero)
  1890. {   if (routedtype == HERO)
  1891.     {   hero[routed].glory -= 2;
  1892.         if (hero[routed].glory < 0)
  1893.         {   hero[routed].glory = 0;
  1894.     }   }
  1895.  
  1896.     if (routertype == HERO || routertype == JARL)
  1897.     {   if (routedtype == KINGDOM)
  1898.         {   world[routed].hero = routerhero;
  1899.             darken();
  1900.             saywho(routertype, router, FALSE, FALSE);
  1901.             strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_HAS_CONQUERED_KINGDOM, "has conquered kingdom"));
  1902.             strcat(saystring, " ");
  1903.             strcat(saystring, world[routed].name);
  1904.             strcat(saystring, " (");
  1905.             stcl_d(numberstring, world[routed].tax);
  1906.             strcat(saystring, numberstring);
  1907.             strcat(saystring, ").");
  1908.             say(LOWER);
  1909.             anykey();
  1910.         } elif (routedtype == JARL)
  1911.         {   if
  1912.             (   routerhero != -1
  1913.              && hero[routerhero].where == jarl[routed].where
  1914.              && !recruit(routed, routerhero)
  1915.             )
  1916.             {   saywho(JARL, routed, FALSE, FALSE);
  1917.                 strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_IS_ROUTED, "is routed"));
  1918.                 strcat(saystring, "!");
  1919.                 say(LOWER);
  1920.                 anykey();
  1921.  
  1922.                 if (routertype == HERO)
  1923.                 {   if (hero[router].control == AMIGA)
  1924.                     {   amiga_rout(JARL, routed);
  1925.                     } else
  1926.                     {   // assert(hero[router].control == HUMAN);
  1927.                         human_rout(JARL, routed, routerhero);
  1928.                 }   }
  1929.                 else
  1930.                 {   // assert(routertype == JARL);
  1931.                     if (jarl[router].hero == -1 || hero[jarl[router].hero].control == AMIGA)
  1932.                     {   amiga_rout(JARL, routed);
  1933.                     } else
  1934.                     {   human_rout(JARL, routed, routerhero);
  1935.         }   }   }   }
  1936.         elif (routedtype == HERO)
  1937.         {   saywho(HERO, routed, FALSE, FALSE);
  1938.             strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_IS_ROUTED, "is routed"));
  1939.             strcat(saystring, "!");
  1940.             say(LOWER);
  1941.             anykey();
  1942.  
  1943.             if (routertype == HERO)
  1944.             {   if (hero[router].control == AMIGA)
  1945.                 {   amiga_rout(HERO, routed);
  1946.                 } else
  1947.                 {   // assert(hero[router].control == HUMAN);
  1948.                     human_rout(HERO, routed, routerhero);
  1949.             }   }
  1950.             else
  1951.             {   // assert(routertype == JARL);
  1952.                 if (jarl[router].hero == -1 || hero[jarl[router].hero].control == AMIGA)
  1953.                 {   amiga_rout(HERO, routed);
  1954.                 } else
  1955.                 {   human_rout(HERO, routed, routerhero);
  1956.         }   }   }
  1957.         elif (routedtype == MONSTER)
  1958.         {   strcpy(saystring, monstertypes[monster[routed].species]);
  1959.             strcat(saystring, " ");
  1960.             strcat(saystring, monster[routed].name);
  1961.             strcat(saystring, " ");
  1962.             strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_IS_ROUTED, "is routed"));
  1963.             strcat(saystring, "!");
  1964.             say(LOWER);
  1965.             anykey();
  1966.  
  1967.             if (routertype == HERO)
  1968.             {   if (hero[router].control == AMIGA)
  1969.                 {   amiga_rout(MONSTER, routed);
  1970.                 } else
  1971.                 {   // assert(hero[router].control == HUMAN);
  1972.                     human_rout(MONSTER, routed, routerhero);
  1973.             }   }
  1974.             else
  1975.             {   // assert(routertype == JARL);
  1976.                 if (jarl[router].hero == -1 || hero[jarl[router].hero].control == AMIGA)
  1977.                 {   amiga_rout(MONSTER, routed);
  1978.                 } else
  1979.                 {   human_rout(MONSTER, routed, routerhero);
  1980.     }   }   }   }
  1981.     else
  1982.     {   // assert(routertype == MONSTER || routertype == KINGDOM);
  1983.         if (routedtype == JARL)
  1984.         {   saywho(JARL, routed, FALSE, FALSE);
  1985.             strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_IS_ROUTED, "is routed"));
  1986.             strcat(saystring, "!");
  1987.             say(LOWER);
  1988.             anykey();
  1989.  
  1990.             amiga_rout(JARL, routed);
  1991.         } elif (routedtype == HERO)
  1992.         {   saywho(HERO, routed, FALSE, FALSE);
  1993.             strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_IS_ROUTED, "is routed"));
  1994.             strcat(saystring, "!");
  1995.             say(LOWER);
  1996.             anykey();
  1997.  
  1998.             amiga_rout(HERO, routed);
  1999. }   }   }
  2000.  
  2001. MODULE void wound(SLONG woundertype, SLONG wounder, SLONG wounderhero, SLONG woundedtype, SLONG wounded, SLONG woundedhero)
  2002. {   SLONG glory = 0, luck = 0, whichtreasure, whichsord;
  2003.  
  2004.     /* WOUNDED. Heroes on the wounded side are wounded.
  2005.     Jarls on the wounded side are removed from the board and placed,
  2006.     upside down, in their respective piles, from which they will reenter
  2007.     play normally. There is no further effect from being wounded, except
  2008.     that jarls that reenter play after being wounded are to be considered
  2009.     unrecruited jarls. */
  2010.  
  2011.     if (woundedtype == HERO)
  2012.     {   if (hero[wounded].wounded)
  2013.         {   kill(woundertype, wounder, wounderhero, woundedtype, wounded, woundedhero);
  2014.             return;
  2015.         }
  2016.  
  2017.         hero[wounded].wounded = TRUE;
  2018.         saywho(HERO, wounded, FALSE, FALSE);
  2019.         strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_IS_WOUNDED, "is wounded"));
  2020.         strcat(saystring, "!");
  2021.         say(LOWER);
  2022.         anykey();
  2023.  
  2024.         if (hero[wounded].maidens)
  2025.         {   hero[wounded].maidens--;
  2026.             hero[wounded].wounded = FALSE;
  2027.  
  2028.             strcpy(saystring, "Frey ");
  2029.             strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_SENDS_A_MAIDEN_TO_HEAL_HERO, "Frey sends a maiden to heal hero"));
  2030.             strcat(saystring, " ");
  2031.             strcat(saystring, hero[wounded].name);
  2032.             strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_S_WOUND, "'s wound"));
  2033.             strcat(saystring, ".");
  2034.             say(LOWER);
  2035.             anykey();
  2036.         }
  2037.  
  2038.         if (wounderhero != -1)
  2039.         {   gain(wounderhero, hero[woundedhero].strength / 2 / 2, hero[woundedhero].strength / 2 / 2);
  2040.     }   }
  2041.     elif (woundedtype == JARL)
  2042.     {   if
  2043.         (   wounderhero != -1
  2044.          && hero[wounderhero].where == jarl[wounded].where
  2045.          && !recruit(wounded, wounderhero)
  2046.         )
  2047.         {   jarl[wounded].alive  = FALSE;
  2048.             jarl[wounded].taken  = FALSE;
  2049.             jarl[wounded].hero   = -1;
  2050.             jarl[wounded].wealth = 0; // this is actually an ambiguity in the rules
  2051.             remove_jarl(wounded, TRUE);
  2052.          
  2053.             for (whichtreasure = 0; whichtreasure <= TREASURES; whichtreasure++)
  2054.             {   if
  2055.                 (   treasure[whichtreasure].possessortype == JARL
  2056.                  && treasure[whichtreasure].possessor == wounded
  2057.                 )
  2058.                 {   // drop the treasure
  2059.                     treasure[whichtreasure].possessortype = KINGDOM;
  2060.                     treasure[whichtreasure].possessor     = -1;
  2061.                     treasure[whichtreasure].where         = jarl[wounded].where;
  2062.                     move_treasure(whichtreasure, TRUE);
  2063.             }   }
  2064.             for (whichsord = 0; whichsord <= SORDS; whichsord++)
  2065.             {   if
  2066.                 (   sord[whichsord].possessortype == JARL
  2067.                  && sord[whichsord].possessor == wounded
  2068.                 )
  2069.                 {   // drop the sword
  2070.                     sord[whichsord].possessortype = KINGDOM;
  2071.                     sord[whichsord].possessor     = -1;
  2072.                     sord[whichsord].where         = jarl[wounded].where;
  2073.                     move_sord(whichsord, TRUE);
  2074.             }   }
  2075.  
  2076.             saywho(JARL, wounded, FALSE, FALSE);
  2077.             strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_IS_WOUNDED, "is wounded"));
  2078.             strcat(saystring, "!");
  2079.             say(LOWER);
  2080.             anykey();
  2081.  
  2082.             if (wounderhero != -1)
  2083.             {   gain(wounderhero, jarl[wounded].strength / 2 / 2, jarl[wounded].strength / 2 / 2); // not the same as / 4 due to rounding
  2084.     }   }   }
  2085.     elif (woundedtype == KINGDOM)
  2086.     {   world[wounded].hero = wounderhero;
  2087.         darken();
  2088.  
  2089.         saywho(woundertype, wounder, FALSE, FALSE);
  2090.         strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_HAS_CONQUERED_KINGDOM, "has conquered kingdom"));
  2091.         strcat(saystring, " ");
  2092.         strcat(saystring, world[wounded].name);
  2093.         strcat(saystring, " (");
  2094.         stcl_d(numberstring, world[wounded].tax);
  2095.         strcat(saystring, numberstring);
  2096.         strcat(saystring, ").");
  2097.         say(LOWER);
  2098.         anykey();
  2099.     } elif (woundedtype == MONSTER)
  2100.     {   monster[wounded].alive = FALSE;
  2101.         monster[wounded].taken = FALSE;
  2102.         remove_monster(wounded, TRUE);
  2103.  
  2104.         strcpy(saystring, monstertypes[monster[wounded].species]);
  2105.         strcat(saystring, " ");
  2106.         strcat(saystring, monster[wounded].name);
  2107.         strcat(saystring, " ");
  2108.         strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_IS_WOUNDED, "is wounded"));
  2109.         strcat(saystring, "!");
  2110.         say(LOWER);
  2111.         anykey();
  2112.        
  2113.         for (whichtreasure = 0; whichtreasure <= TREASURES; whichtreasure++)
  2114.         {   if
  2115.             (   treasure[whichtreasure].possessortype == MONSTER
  2116.              && treasure[whichtreasure].possessor == wounded
  2117.             )
  2118.             {   // give the treasure to the wounder of the dragon
  2119.                 // assert(monster[wounded].species == DRAGON);
  2120.                 treasure[whichtreasure].possessortype = woundertype;
  2121.                 treasure[whichtreasure].possessor     = wounder;
  2122.                 treasure[whichtreasure].where         = -1;
  2123.  
  2124.                 saywho(woundertype, wounder, FALSE, FALSE);
  2125.                 strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_FINDS_THE, "finds the"));
  2126.                 strcat(saystring, " ");
  2127.                 strcat(saystring, treasure[whichtreasure].name);
  2128.                 strcat(saystring, ".");
  2129.                 say(LOWER);
  2130.                 anykey();
  2131.         }   }
  2132.  
  2133.         if (monster[wounded].wealth > 0)
  2134.         {   hero[wounderhero].wealth += monster[wounded].wealth;
  2135.  
  2136.             saywho(woundertype, wounder, FALSE, FALSE);
  2137.             strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_FINDS, "finds"));
  2138.             strcat(saystring, " ");
  2139.             stcl_d(numberstring, monster[wounded].wealth);
  2140.             strcat(saystring, numberstring);
  2141.             strcat(saystring, " ");
  2142.             strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_GOLDEN_MARKS, "golden marks"));
  2143.             strcat(saystring, ".");
  2144.             say(LOWER);
  2145.             anykey();
  2146.         }
  2147.  
  2148.         switch (monster[wounded].species)
  2149.         {
  2150.         case DRAGON:
  2151.             glory = 6;
  2152.             luck  = 5;
  2153.         break;
  2154.         case DROW:
  2155.             glory = 3;
  2156.             luck  = 2;
  2157.         break;
  2158.         case GHOST:
  2159.             glory = 2;
  2160.             luck  = 2;
  2161.         break;
  2162.         case GIANT:
  2163.             glory = 4;
  2164.             luck  = 3;
  2165.         break;
  2166.         case TROLL:
  2167.             glory = 3;
  2168.             luck  = 3;
  2169.         break;
  2170.         case WITCH:
  2171.             glory = 5;
  2172.             luck  = 4;
  2173.         break;
  2174.         default:
  2175.             // assert(0);
  2176.         break;
  2177.         }
  2178.         glory /= 2;
  2179.         luck  /= 2;
  2180.  
  2181.         // assert(wounderhero != -1);
  2182.         gain(wounderhero, glory, luck);
  2183. }   }
  2184. MODULE void kill(SLONG killertype, SLONG killer, SLONG killerhero, SLONG killedtype, SLONG killed, SLONG killedhero)
  2185. {   SLONG glory = 0, luck = 0, result, whichjarl, whichtreasure, whichsord;
  2186.  
  2187.     if (killedtype == HERO)
  2188.     {   hero[killed].alive     =
  2189.         hero[killed].attacking =
  2190.         hero[killed].defending = FALSE;
  2191.         remove_hero(killed, TRUE);
  2192.  
  2193.         for (whichtreasure = 0; whichtreasure <= TREASURES; whichtreasure++)
  2194.         {   if
  2195.             (   treasure[whichtreasure].possessortype == HERO
  2196.              && treasure[whichtreasure].possessor == killed
  2197.             )
  2198.             {   // drop the treasure
  2199.                 treasure[whichtreasure].possessortype = KINGDOM;
  2200.                 treasure[whichtreasure].possessor     = -1;
  2201.                 treasure[whichtreasure].where         = hero[killed].where;
  2202.                 move_treasure(whichtreasure, TRUE);
  2203.         }   }
  2204.         for (whichsord = 0; whichsord <= SORDS; whichsord++)
  2205.         {   if
  2206.             (   sord[whichsord].possessortype == HERO
  2207.              && sord[whichsord].possessor == killed
  2208.             )
  2209.             {   // drop the sword
  2210.                 sord[whichsord].possessortype = KINGDOM;
  2211.                 sord[whichsord].possessor     = -1;
  2212.                 sord[whichsord].where         = hero[killed].where;
  2213.                 move_sord(whichsord, TRUE);
  2214.         }   }
  2215.  
  2216.         saywho(HERO, killed, FALSE, FALSE);
  2217.         strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_IS_KILLED, "is killed"));
  2218.         strcat(saystring, "!");
  2219.         say(LOWER);
  2220.         anykey();
  2221.  
  2222.         if (killerhero != -1)
  2223.         {   gain(killerhero, hero[killedhero].strength / 2, hero[killedhero].strength / 2);
  2224.     }   }
  2225.     elif (killedtype == JARL)
  2226.     {   if
  2227.         (   killerhero == -1
  2228.          || hero[killerhero].where != jarl[killed].where
  2229.          || !recruit(killed, killerhero)
  2230.         )
  2231.         {   jarl[killed].alive     =
  2232.             jarl[killed].attacking =
  2233.             jarl[killed].defending = FALSE;
  2234.             remove_jarl(killed, TRUE);
  2235.             
  2236.             for (whichtreasure = 0; whichtreasure <= TREASURES; whichtreasure++)
  2237.             {   if
  2238.                 (   treasure[whichtreasure].possessortype == JARL
  2239.                  && treasure[whichtreasure].possessor == killed
  2240.                 )
  2241.                 {   // drop the treasure
  2242.                     treasure[whichtreasure].possessortype = KINGDOM;
  2243.                     treasure[whichtreasure].possessor     = -1;
  2244.                     treasure[whichtreasure].where         = jarl[killed].where;
  2245.                     move_treasure(whichtreasure, TRUE);
  2246.             }   }
  2247.             for (whichsord = 0; whichsord <= SORDS; whichsord++)
  2248.             {   if
  2249.                 (   sord[whichsord].possessortype == JARL
  2250.                  && sord[whichsord].possessor == killed
  2251.                 )
  2252.                 {   // drop the treasure
  2253.                     sord[whichsord].possessortype = KINGDOM;
  2254.                     sord[whichsord].possessor     = -1;
  2255.                     sord[whichsord].where         = jarl[killed].where;
  2256.                     move_sord(whichsord, TRUE);
  2257.             }   }
  2258.  
  2259.             saywho(JARL, killed, FALSE, FALSE);
  2260.             strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_IS_KILLED, "is killed"));
  2261.             strcat(saystring, "!");
  2262.             say(LOWER);
  2263.             anykey();
  2264.  
  2265.             if (killerhero != -1 && killedtype == JARL)
  2266.             {   if (hero[killerhero].where == jarl[killed].where)
  2267.                 {   if (jarl[killed].wealth)
  2268.                     {   hero[killerhero].wealth += jarl[killed].wealth;
  2269.                         saywho(HERO, killerhero, FALSE, FALSE);
  2270.                         strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_TAKES, "takes"));
  2271.                         strcat(saystring, " ");
  2272.                         stcl_d(numberstring, jarl[killed].wealth);
  2273.                         strcat(saystring, " ");
  2274.                         strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_GOLDEN_MARKS, "golden marks"));
  2275.                         strcat(saystring, " ");
  2276.                         strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_FROM, "from"));
  2277.                         strcat(saystring, " ");
  2278.                         saywho(JARL, killed, FALSE, TRUE);
  2279.                         strcat(saystring, ".");
  2280.                         say(LOWER);
  2281.                         anykey();
  2282.                 }   }
  2283.                 else
  2284.                 {   for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
  2285.                     {   if
  2286.                         (   jarl[whichjarl].alive
  2287.                          && jarl[whichjarl].hero == killerhero
  2288.                          && jarl[whichjarl].where == jarl[killed].where
  2289.                         )
  2290.                         {   assert(whichjarl != killed);
  2291.  
  2292.                             if (jarl[killed].wealth)
  2293.                             {   jarl[whichjarl].wealth += jarl[killed].wealth;
  2294.                                 saywho(JARL, whichjarl, FALSE, FALSE);
  2295.                                 strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_TAKES, "takes"));
  2296.                                 strcat(saystring, " ");
  2297.                                 stcl_d(numberstring, jarl[killed].wealth);
  2298.                                 strcat(saystring, " ");
  2299.                                 strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_GOLDEN_MARKS, "golden marks"));
  2300.                                 strcat(saystring, " ");
  2301.                                 strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_FROM, "from"));
  2302.                                 strcat(saystring, " ");
  2303.                                 saywho(JARL, killed, FALSE, TRUE);
  2304.                                 strcat(saystring, ".");
  2305.                                 say(LOWER);
  2306.                                 anykey();
  2307.             }   }   }   }   }
  2308.  
  2309.             if (killedhero != -1)
  2310.             {   if (hero[killedhero].control == HUMAN)
  2311.                 {   saywho(HERO, killedhero, TRUE, FALSE);
  2312.                     strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_LOSE, "lose"));
  2313.                     strcat(saystring, " ");
  2314.                     stcl_d(numberstring, jarl[killed].strength / 2);
  2315.                     strcat(saystring, numberstring);
  2316.                     strcat(saystring, " (");
  2317.                     strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_CHAR_GLORY, "G"));
  2318.                     strcat(saystring, ")");
  2319.                     strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_UNCHAR_GLORY, "lory"));
  2320.                     strcat(saystring, " ");
  2321.                     strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_OR, "or"));
  2322.                     strcat(saystring, " ");
  2323.                     stcl_d(numberstring, jarl[killed].strength / 2);
  2324.                     strcat(saystring, numberstring);
  2325.                     strcat(saystring, " (");
  2326.                     strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_CHAR_LUCK, "L"));
  2327.                     strcat(saystring, ")");
  2328.                     strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_UNCHAR_LUCK, "uck"));
  2329.                     strcat(saystring, "?");
  2330.                     say(LOWER);
  2331.                     do
  2332.                     {   result = getevent(KEYBOARD, NULL);
  2333.                     } while (result != onekey[ONEKEY_GLORY] && result != onekey[ONEKEY_LUCK]);
  2334.                     if (result == onekey[ONEKEY_GLORY])
  2335.                     {   hero[killedhero].glory -= jarl[killed].strength / 2;
  2336.                         if (hero[killedhero].glory < 0)
  2337.                         {   hero[killedhero].glory = 0;
  2338.                     }   }
  2339.                     else
  2340.                     {   // assert(result == onekey[ONEKEY_LUCK]);
  2341.                         hero[killedhero].luck  -= jarl[killed].strength / 2;
  2342.                         if (hero[killedhero].luck < 0)
  2343.                         {   hero[killedhero].luck = 0;
  2344.                 }   }   }
  2345.                 else
  2346.                 {   // assert(hero[killedhero].control == AMIGA);
  2347.                     hero[killedhero].glory -= jarl[killed].strength / 2;
  2348.                     if (hero[killedhero].glory < 0)
  2349.                     {   hero[killedhero].glory = 0;
  2350.             }   }   }
  2351.             if (killerhero != -1)
  2352.             {   gain(killerhero, jarl[killed].strength / 2, jarl[killed].strength / 2);
  2353.     }   }   }
  2354.     elif (killedtype == KINGDOM)
  2355.     {   world[killed].hero = killerhero;
  2356.         darken();
  2357.         saywho(HERO, killerhero, FALSE, FALSE);
  2358.         strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_HAS_CONQUERED_KINGDOM, "has conquered kingdom"));
  2359.         strcat(saystring, " ");
  2360.         strcat(saystring, world[killed].name);
  2361.         strcat(saystring, " (");
  2362.         stcl_d(numberstring, world[killed].tax);
  2363.         strcat(saystring, numberstring);
  2364.         strcat(saystring, ").");
  2365.         say(LOWER);
  2366.         anykey();
  2367.     } elif (killedtype == MONSTER)
  2368.     {   monster[killed].alive = FALSE;
  2369.         remove_monster(killed, TRUE);
  2370.  
  2371.         strcpy(saystring, monstertypes[monster[killed].species]);
  2372.         strcat(saystring, " ");
  2373.         strcat(saystring, monster[killed].name);
  2374.         strcat(saystring, " ");
  2375.         strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_IS_KILLED, "is killed"));
  2376.         strcat(saystring, "!");
  2377.         say(LOWER);
  2378.         anykey();
  2379.  
  2380.         for (whichtreasure = 0; whichtreasure <= TREASURES; whichtreasure++)
  2381.         {   if
  2382.             (   treasure[whichtreasure].possessortype == MONSTER
  2383.              && treasure[whichtreasure].possessor == killed
  2384.             )
  2385.             {   // give the treasure to the killer of the dragon
  2386.                 // assert(monster[killed].species == DRAGON);
  2387.                 treasure[whichtreasure].possessortype = killertype;
  2388.                 treasure[whichtreasure].possessor     = killer;
  2389.                 treasure[whichtreasure].where         = -1;
  2390.  
  2391.                 saywho(killertype, killer, FALSE, FALSE);
  2392.                 strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_FINDS_THE, "finds the"));
  2393.                 strcat(saystring, " ");
  2394.                 strcat(saystring, treasure[whichtreasure].name);
  2395.                 strcat(saystring, ".");
  2396.                 say(LOWER);
  2397.                 anykey();
  2398.         }   }
  2399.  
  2400.         if (monster[killed].wealth > 0)
  2401.         {   hero[killerhero].wealth += monster[killed].wealth;
  2402.  
  2403.             saywho(killertype, killer, FALSE, FALSE);
  2404.             strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_FINDS, "finds"));
  2405.             strcat(saystring, " ");
  2406.             stcl_d(numberstring, monster[killed].wealth);
  2407.             strcat(saystring, numberstring);
  2408.             strcat(saystring, " ");
  2409.             strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_GOLDEN_MARKS, "golden marks"));
  2410.             strcat(saystring, ".");
  2411.             say(LOWER);
  2412.             anykey();
  2413.         }
  2414.  
  2415.         switch (monster[killed].species)
  2416.         {
  2417.         case DRAGON:
  2418.             glory = 6;
  2419.             luck  = 5;
  2420.         break;
  2421.         case DROW:
  2422.             glory = 3;
  2423.             luck  = 2;
  2424.         break;
  2425.         case GHOST:
  2426.             glory = 2;
  2427.             luck  = 2;
  2428.         break;
  2429.         case GIANT:
  2430.             glory = 4;
  2431.             luck  = 3;
  2432.         break;
  2433.         case TROLL:
  2434.             glory = 3;
  2435.             luck  = 3;
  2436.         break;
  2437.         case WITCH:
  2438.             glory = 5;
  2439.             luck  = 4;
  2440.         break;
  2441.         default:
  2442.             // assert(0);
  2443.         break;
  2444.         }
  2445.         // assert(killerhero != -1);
  2446.         gain(killerhero, glory, luck);
  2447.  
  2448.         // check if hero was present at the combat
  2449.         if
  2450.         (   killerhero != -1
  2451.          && hero[killerhero].attacking
  2452.         )
  2453.         {   if
  2454.             (   (   monster[killed].species == DROW
  2455.                  || monster[killed].species == GHOST
  2456.                  || monster[killed].species == WITCH
  2457.                 )
  2458.              && hero[killer].rune == -1
  2459.             )
  2460.             {   hero[killer].rune = rand() % (RUNES + 1);
  2461.                 saywho(HERO, killer, FALSE, FALSE);
  2462.                 strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_LEARNS_THE_RUNE, "learns the rune"));
  2463.                 strcat(saystring, " ");
  2464.                 strcat(saystring, runename[hero[killer].rune]);
  2465.                 strcat(saystring, ", ");
  2466.                 strcat(saystring, runedesc[hero[killer].rune]);
  2467.                 strcat(saystring, ".");
  2468.                 say(LOWER);
  2469.                 anykey();
  2470. }   }   }   }
  2471.  
  2472. MODULE FLAG recruit(SLONG recruited, SLONG recruiterhero)
  2473. {   SLONG jarls = 0,
  2474.           result,
  2475.           whichjarl;
  2476.  
  2477.     if (jarl[recruited].hero == -1 && hero[recruiterhero].luck >= 1 && jarl[recruited].recruitable)
  2478.     {   jarl[recruited].recruitable = FALSE;
  2479.         for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
  2480.         {   if (jarl[whichjarl].alive && jarl[whichjarl].hero == recruiterhero)
  2481.             {   jarls++;
  2482.         }   }
  2483.         if (jarls <= 3)
  2484.         {   if (hero[recruiterhero].control == HUMAN)
  2485.             {   saywho(HERO, recruiterhero, TRUE, FALSE);
  2486.                 strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_RECRUIT_JARL, "recruit jarl"));
  2487.                 strcat(saystring, " ");
  2488.                 strcat(saystring, jarl[recruited].name);
  2489.                 strcat(saystring, " (");
  2490.                 strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_CHAR_YES, "Y"));
  2491.                 strcat(saystring, "/");
  2492.                 strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_CHAR_NO, "N"));
  2493.                 strcat(saystring, ")?");
  2494.                 say(LOWER);
  2495.                 do
  2496.                 {   result = getevent(KEYBOARD, NULL);
  2497.                 } while (result != onekey[ONEKEY_YES] && result != onekey[ONEKEY_NO]);
  2498.                 if (result == onekey[ONEKEY_YES])
  2499.                 {   hero[recruiterhero].luck--;
  2500.                     gain(recruiterhero, jarl[recruited].strength / 2, jarl[recruited].strength / 2);
  2501.                     jarl[recruited].hero = recruiterhero;
  2502.                     return(TRUE);
  2503.                 } else
  2504.                 {   // assert(result == onekey[ONEKEY_NO]);
  2505.             }   }
  2506.             else
  2507.             {   // assert(hero[recruiterhero].control == AMIGA);
  2508.                 hero[recruiterhero].luck--;
  2509.                 gain(recruiterhero, jarl[recruited].strength / 2, jarl[recruited].strength / 2);
  2510.                 jarl[recruited].hero = recruiterhero;
  2511.                 saywho(HERO, recruiterhero, FALSE, FALSE);
  2512.                 strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_RECRUITS_JARL, "recruits jarl"));
  2513.                 strcat(saystring, " ");
  2514.                 strcat(saystring, jarl[recruited].name);
  2515.                 strcat(saystring, ".");
  2516.                 say(LOWER);
  2517.                 anykey();
  2518.                 return(TRUE);
  2519.     }   }   }
  2520.  
  2521.     return(FALSE);
  2522. }
  2523.  
  2524. MODULE SLONG d6(void)
  2525. {   return((rand() % 6) + 1);
  2526. }
  2527.  
  2528. AGLOBAL void cleanexit(SLONG rc)
  2529. {   BPTR  FileHandle /* = NULL */ ;
  2530.     SLONG whichhero;
  2531.  
  2532.     destroycounters();
  2533.  
  2534.     if (ASLRqPtr)
  2535.     {   FreeAslRequest(ASLRqPtr);
  2536.         ASLRqPtr = NULL;
  2537.     }
  2538.     if (OldWindowPtr)
  2539.     {   ProcessPtr->pr_WindowPtr = OldWindowPtr;
  2540.     }
  2541.  
  2542.     /* It does not matter whether there are outstanding messages for a
  2543.     window when it is closed, provided that the window does not use a
  2544.     shared IDCMP message port. */
  2545.  
  2546.     if (HelpWindowPtr)
  2547.     {   CloseWindow(HelpWindowPtr);
  2548.         HelpWindowPtr = NULL;
  2549.     }
  2550.     if (MainWindowPtr)
  2551.     {   ClearMenuStrip(MainWindowPtr);
  2552.         CloseWindow(MainWindowPtr);
  2553.         MainWindowPtr = NULL;
  2554.     }
  2555.     if (GListPtr)
  2556.     {   FreeGadgets(GListPtr);
  2557.         GListPtr = NULL;
  2558.     }
  2559.     if (MenuPtr)
  2560.     {   FreeMenus(MenuPtr);
  2561.         MenuPtr = NULL;
  2562.     }
  2563.     if (VisualInfoPtr)
  2564.     {   FreeVisualInfo(VisualInfoPtr);
  2565.         VisualInfoPtr = NULL;
  2566.     }
  2567.     if (ScreenPtr)
  2568.     {   CloseScreen(ScreenPtr);
  2569.         ScreenPtr = NULL;
  2570.     }
  2571.     if (ASLBase)
  2572.     {   CloseLibrary((struct Library *) ASLBase);
  2573.         ASLBase = NULL;
  2574.     }
  2575.     if (GadToolsBase)
  2576.     {   CloseLibrary((struct Library *) GadToolsBase);
  2577.         GadToolsBase = NULL;
  2578.     }
  2579.     if (GfxBase)
  2580.     {   CloseLibrary((struct Library *) GfxBase);
  2581.         GfxBase = NULL;
  2582.     }
  2583.     if (LocaleBase)
  2584.     {   CloseCatalog(li.li_Catalog);
  2585.         CloseLibrary((struct Library *) LocaleBase);
  2586.         LocaleBase = NULL;
  2587.     }
  2588.     if (IntuitionBase)
  2589.     {   OpenWorkBench();
  2590.         CloseLibrary((struct Library *) IntuitionBase);
  2591.         IntuitionBase = NULL;
  2592.     }
  2593.     if (ArgsPtr)
  2594.     {   FreeArgs(ArgsPtr);
  2595.         ArgsPtr = NULL;
  2596.     }
  2597.  
  2598.     for (whichhero = 0; whichhero <= HEROES; whichhero++)
  2599.     {    IOBuffer[whichhero] = (SBYTE) hero[whichhero].control;
  2600.     }
  2601.     IOBuffer[ 6] = (UBYTE)   (DisplayID     / 16777216);
  2602.     IOBuffer[ 7] = (UBYTE)  ((DisplayID     % 16777216) / 65536);
  2603.     IOBuffer[ 8] = (UBYTE) (((DisplayID     % 16777216) % 65536) / 256);
  2604.     IOBuffer[ 9] = (UBYTE) (((DisplayID     % 16777216) % 65536) % 256);
  2605.     IOBuffer[10] = (UBYTE)   (DisplayWidth  / 16777216);
  2606.     IOBuffer[11] = (UBYTE)  ((DisplayWidth  % 16777216) / 65536);
  2607.     IOBuffer[12] = (UBYTE) (((DisplayWidth  % 16777216) % 65536) / 256);
  2608.     IOBuffer[13] = (UBYTE) (((DisplayWidth  % 16777216) % 65536) % 256);
  2609.     IOBuffer[14] = (UBYTE)   (DisplayHeight / 16777216);
  2610.     IOBuffer[15] = (UBYTE)  ((DisplayHeight % 16777216) / 65536);
  2611.     IOBuffer[16] = (UBYTE) (((DisplayHeight % 16777216) % 65536) / 256);
  2612.     IOBuffer[17] = (UBYTE) (((DisplayHeight % 16777216) % 65536) % 256);
  2613.     IOBuffer[18] = (UBYTE)   (DisplayDepth  / 65536);
  2614.     IOBuffer[19] = (UBYTE)   (DisplayDepth  % 65536);
  2615.     IOBuffer[20] = (UBYTE)    speed;
  2616.     if (FileHandle = Open("PROGDIR:Saga.config", MODE_NEWFILE))
  2617.     {   Write(FileHandle, IOBuffer, 21);
  2618.         Close(FileHandle);
  2619.         // FileHandle = NULL;
  2620.     }
  2621.  
  2622.     exit(rc); // End of program.
  2623. }
  2624.  
  2625. MODULE void say(SLONG position)
  2626. {   SLONG length;
  2627.  
  2628.     length = strlen(saystring);
  2629.  
  2630.     SetAPen(MainWindowPtr->RPort, BLACK);
  2631.     if (position == UPPER)
  2632.     {   RectFill
  2633.         (   MainWindowPtr->RPort,
  2634.             0,   MESSAGEY,
  2635.             639, MESSAGEY + 7
  2636.         );
  2637.         Move(MainWindowPtr->RPort, 4, MESSAGEY + 6);
  2638.     }
  2639.     else
  2640.     {   // assert(position == LOWER);
  2641.         RectFill
  2642.         (   MainWindowPtr->RPort,
  2643.             0,   MESSAGEY + 10,
  2644.             639, MESSAGEY + 27
  2645.         );
  2646.         Move(MainWindowPtr->RPort, 4, MESSAGEY + 16);
  2647.     }
  2648.  
  2649.     SetAPen(MainWindowPtr->RPort, WHITE);
  2650.     if (position == LOWER && length > 79)
  2651.     {   Text(MainWindowPtr->RPort, saystring, 79);
  2652.         Move(MainWindowPtr->RPort, 4, MESSAGEY + 26);
  2653.         Text(MainWindowPtr->RPort, &saystring[79], length - 79);
  2654.     } else
  2655.     {   Text(MainWindowPtr->RPort, saystring, length);
  2656. }   }
  2657.  
  2658. MODULE void newhero(SLONG whichhero, FLAG givesord)
  2659. {   SLONG whichjarl, whichsord;
  2660.  
  2661.     hero[whichhero].where     =
  2662.     hero[whichhero].homewhere = rand() % 36;
  2663.     hero[whichhero].glory     =
  2664.     hero[whichhero].wealth    = 0;
  2665.     hero[whichhero].luck      = 3;
  2666.     hero[whichhero].alive     = TRUE;
  2667.     hero[whichhero].verydead  =
  2668.     hero[whichhero].wounded   =
  2669.     hero[whichhero].hagall    =
  2670.     hero[whichhero].loseturn  = FALSE;
  2671.     hero[whichhero].rune      =
  2672.     hero[whichhero].god       = -1;
  2673.     hero[whichhero].sea       = NORMAL;
  2674.     hero[whichhero].maidens   = 0;
  2675.     if (givesord)
  2676.     {   hero[whichhero].promoted = -1;
  2677.     }
  2678.  
  2679.     for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
  2680.     {   if (jarl[whichjarl].hero == whichhero)
  2681.         {   jarl[whichjarl].hero = -1;
  2682.     }   }
  2683.  
  2684.     move_hero(whichhero, TRUE);
  2685.     // we don't unslot newborn counters
  2686.  
  2687.     if (!givesord)
  2688.     {   return;
  2689.     }
  2690.     
  2691.     // at least one sword should should always be available
  2692.     do
  2693.     {   whichsord = rand() % 6;
  2694.     } while (sord[whichsord].taken);
  2695.     sord[whichsord].taken         = TRUE;
  2696.     sord[whichsord].possessortype = HERO;
  2697.     sord[whichsord].possessor     = whichhero;
  2698.     sord[whichsord].where         = -1;
  2699. }
  2700.  
  2701. MODULE SLONG getevent(SLONG mode, SLONG* countertype)
  2702. {   AUTO    UWORD                code,
  2703.                                  qual;
  2704.     AUTO    ULONG                class;
  2705.     AUTO    struct IntuiMessage* MsgPtr;
  2706.     AUTO    LONG                 country;
  2707.     AUTO    SLONG                counter,
  2708.                                  ticks = 0;
  2709.     AUTO    WORD                 mousex, mousey;
  2710.     AUTO    struct MenuItem*     ItemPtr;
  2711.     PERSIST SLONG                cheat = 0;
  2712.  
  2713.     /* return codes:
  2714.     -4: Escape
  2715.     -3: spacebar
  2716.     -2: backspace
  2717.     -1: invalid country */
  2718.  
  2719.     while(1)
  2720.     {   while (MsgPtr = (struct IntuiMessage *) GT_GetIMsg(MainWindowPtr->UserPort))
  2721.         {   class  = MsgPtr->Class;
  2722.             code   = MsgPtr->Code;
  2723.             mousex = MsgPtr->MouseX;
  2724.             mousey = MsgPtr->MouseY;
  2725.             qual   = MsgPtr->Qualifier;
  2726.             if (class == IDCMP_MENUVERIFY && code == MENUHOT && mousey >= 0)
  2727.             {   code = MENUCANCEL;
  2728.                 ReplyMsg(MsgPtr);
  2729.             } else
  2730.             {   GT_ReplyIMsg(MsgPtr); // seems that this doesn't work for menu verify messages
  2731.             }
  2732.             switch(class)
  2733.             {
  2734.             case IDCMP_CLOSEWINDOW:
  2735.                 cleanexit(EXIT_SUCCESS);
  2736.             break;
  2737.             case IDCMP_REFRESHWINDOW:
  2738.                 GT_BeginRefresh(MainWindowPtr);
  2739.                 GT_EndRefresh(MainWindowPtr, TRUE);
  2740.             break;
  2741.             case IDCMP_MOUSEBUTTONS:
  2742.                 if ((code == MIDDLEDOWN || code == MENUUP) && !(qual & IEQUALIFIER_REPEAT))
  2743.                 {   if (mode == KEYBOARD)
  2744.                     {   return('0');
  2745.                     } elif (mode != ANYKEY || tickwait == -1)
  2746.                     {   return(-3);
  2747.                 }   }
  2748.                 elif (code == SELECTDOWN && !(qual & IEQUALIFIER_REPEAT))
  2749.                 {   if (mode == KEYBOARD || (mode == ANYKEY && tickwait == -1))
  2750.                     {   if (mousey >= MESSAGEY)
  2751.                         {   return('0');
  2752.                         } else
  2753.                         {   return(-1);
  2754.                     }   }
  2755.                     elif (mode == COUNTER)
  2756.                     {   if (mousey >= MESSAGEY)
  2757.                         {   return(-3);
  2758.                         }
  2759.                         counter = checkcounters(mousex, mousey, countertype);
  2760.                         if (counter == -1)
  2761.                         {   country = checkcountry(mousex, mousey);
  2762.                             *(countertype) = KINGDOM;
  2763.                             flash(country);
  2764.                             return(country);
  2765.                         } else
  2766.                         {   return(counter);
  2767.                     }   }
  2768.                     elif (mode == COUNTRY)
  2769.                     {   if (mousey >= MESSAGEY)
  2770.                         {   return(-3);
  2771.                         }
  2772.                         counter = checkcounters(mousex, mousey, countertype);
  2773.                         if (counter == -1)
  2774.                         {   country = checkcountry(mousex, mousey);
  2775.                             *(countertype) = KINGDOM;
  2776.                             flash(country);
  2777.                             return(country);
  2778.                         } else
  2779.                         {   if (*(countertype) == HERO)
  2780.                             {   flash(hero[counter].where);
  2781.                                 return(hero[counter].where);
  2782.                             } elif (*(countertype) == JARL)
  2783.                             {   flash(jarl[counter].where);
  2784.                                 return(jarl[counter].where);
  2785.                             } elif (*(countertype) == MONSTER)
  2786.                             {   flash(monster[counter].where);
  2787.                                 return(monster[counter].where);
  2788.                 }   }   }   }
  2789.             break;
  2790.             case IDCMP_INTUITICKS:
  2791.                 if (mode == ANYKEY && tickwait != -1)
  2792.                 {   ticks++;
  2793.                     if (ticks >= tickwait)
  2794.                     {   return(-3);
  2795.                 }   }
  2796.                 counter = checkcounters(mousex, mousey, countertype);
  2797.                 if (counter == -1)
  2798.                 {   country = checkcountry(mousex, mousey);
  2799.                     *(countertype) = KINGDOM;
  2800.                     showcountry(country);
  2801.                 } else
  2802.                 {   if (*(countertype) == HERO)
  2803.                     {   saywho(HERO, counter, FALSE, FALSE);
  2804.                         strcat(saystring, "(");
  2805.                         stcl_d(numberstring, hero[counter].strength);
  2806.                         strcat(saystring, numberstring);
  2807.                         strcat(saystring, "-");
  2808.                         stcl_d(numberstring, hero[counter].moves);
  2809.                         strcat(saystring, numberstring);
  2810.                         strcat(saystring, ")");
  2811.                         say(UPPER);
  2812.                     } elif (*(countertype) == JARL)
  2813.                     {   if (jarl[counter].face == FACEDOWN)
  2814.                         {   strcpy(saystring, GetCatalogStr(li.li_Catalog, MSG_UNKNOWN_JARL, "Unknown jarl"));
  2815.                             strcat(saystring, " (?-?)");
  2816.                         } else
  2817.                         {   saywho(JARL, counter, FALSE, FALSE);
  2818.                             strcat(saystring, "(");
  2819.                             stcl_d(numberstring, jarl[counter].strength);
  2820.                             strcat(saystring, numberstring);
  2821.                             strcat(saystring, "-");
  2822.                             stcl_d(numberstring, jarl[counter].moves);
  2823.                             strcat(saystring, numberstring);
  2824.                             strcat(saystring, ")");
  2825.                         }
  2826.                         say(UPPER);
  2827.                     } elif (*(countertype) == MONSTER)
  2828.                     {   strcpy(saystring, monstertypes[monster[counter].species]);
  2829.                         strcat(saystring, " ");
  2830.                         strcat(saystring, monster[counter].name);
  2831.                         strcat(saystring, " (");
  2832.                         stcl_d(numberstring, monster[counter].strength);
  2833.                         strcat(saystring, numberstring);
  2834.                         strcat(saystring, "-");
  2835.                         stcl_d(numberstring, monster[counter].moves);
  2836.                         strcat(saystring, numberstring);
  2837.                         strcat(saystring, ")");
  2838.                         say(UPPER);
  2839.                     } elif (*(countertype) == TREASURE)
  2840.                     {   strcpy(saystring, GetCatalogStr(li.li_Catalog, MSG_THE, "The"));
  2841.                         strcat(saystring, " ");
  2842.                         strcat(saystring, treasure[counter].name);
  2843.                         strcat(saystring, " ");
  2844.                         strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_TREASURE2, "treasure"));
  2845.                         say(UPPER);
  2846.                     } elif (*(countertype) == SORD)
  2847.                     {   strcpy(saystring, GetCatalogStr(li.li_Catalog, MSG_SWORD, "Sword"));
  2848.                         strcat(saystring, " ");
  2849.                         strcat(saystring, sord[counter].name);
  2850.                         say(UPPER);
  2851.                 }   }
  2852.             break;
  2853.             case IDCMP_VANILLAKEY:
  2854.                 if (code == ' ' && (mode != ANYKEY || tickwait == -1))
  2855.                 {   return(-3);
  2856.                 } elif (code == 27) // Escape
  2857.                 {   if ((qual & IEQUALIFIER_LSHIFT) || (qual & IEQUALIFIER_RSHIFT))
  2858.                     {   cleanexit(EXIT_SUCCESS);
  2859.                     } elif (mode != ANYKEY || tickwait == -1)
  2860.                     {   return(-4);
  2861.                 }   }
  2862.                 elif (mode == KEYBOARD || (mode == ANYKEY && tickwait == -1))
  2863.                 {   code = toupper(code);
  2864.                     return((SLONG) code);
  2865.                 }
  2866.                 elif (code == 8) // backspace
  2867.                 {   if (mode != ANYKEY || tickwait == -1)
  2868.                     {   return(-2);
  2869.                 }   }
  2870.             break;
  2871.             case IDCMP_RAWKEY:
  2872.                 switch(code)
  2873.                 {
  2874.                 case HELP:
  2875.                     counter = checkcounters(mousex, mousey, countertype);
  2876.                     if (counter == -1)
  2877.                     {   country = checkcountry(mousex, mousey);
  2878.                         if (country != -1)
  2879.                         {   infowindow(KINGDOM, country);
  2880.                         } else
  2881.                         {   ; // DisplayBeep(ScreenPtr);
  2882.                     }   }
  2883.                     else
  2884.                     {   infowindow(*(countertype), counter);
  2885.                     }
  2886.                 break;
  2887.                 default:
  2888.                     if
  2889.                     (   (mode == KEYBOARD || (mode == ANYKEY && tickwait == -1))
  2890.                      && code < KEYUP && (code < FIRSTQUALIFIER || code > LASTQUALIFIER)
  2891.                     )
  2892.                     {   if (code == SCAN_F1 + cheat)
  2893.                         {   cheat++;
  2894.                             if (cheat == 5)
  2895.                             {   cheat = 0;
  2896.                                 hero[BEOWULF].luck = 9999;
  2897.                                 DisplayBeep(ScreenPtr);
  2898.                         }   }
  2899.                         else cheat = 0;
  2900.                     }
  2901.                 break;
  2902.                 }
  2903.             break;
  2904.             case IDCMP_MENUPICK:
  2905.                 while (code != MENUNULL)
  2906.                 {   ItemPtr = ItemAddress(MenuPtr, code);
  2907.  
  2908.                     switch (MENUNUM(code))
  2909.                     {
  2910.                     case MN_PROJECT:
  2911.                         switch (ITEMNUM(code))
  2912.                         {
  2913.                         case IN_NEW:
  2914.                             return(-4);
  2915.                         case IN_SAVE:
  2916.                             savegame(FALSE);
  2917.                         break;
  2918.                         case IN_SAVEAS:
  2919.                             savegame(TRUE);
  2920.                         break;
  2921.                         case IN_QUIT:
  2922.                             cleanexit(EXIT_SUCCESS);
  2923.                         break;
  2924.                         default:
  2925.                             // IN_OPEN
  2926.                         break;
  2927.                         }
  2928.                     break;
  2929.                     case MN_HELP:
  2930.                         switch(ITEMNUM(code))
  2931.                         {
  2932.                         case IN_ABOUT:
  2933.                             helpabout();
  2934.                         break;
  2935.                         default:
  2936.                         break;
  2937.                         }
  2938.                     break;
  2939.                     default:
  2940.                     break;
  2941.                     }
  2942.                     code = ItemPtr->NextSelect;
  2943.                 }
  2944.             break;
  2945.             default:
  2946.             break;
  2947. }   }   }   }
  2948.  
  2949. MODULE void showcountry(SLONG country)
  2950. {   if (country >= 0 && country <= 65)
  2951.     {   strcpy(saystring, world[country].name);
  2952.         if (country <= 35)
  2953.         {   strcat(saystring, " (");
  2954.             stcl_d(numberstring, world[country].tax);
  2955.             strcat(saystring, numberstring);
  2956.             strcat(saystring, ")");
  2957.     }   }
  2958.     else
  2959.     {   strcpy(saystring, "-");
  2960.     }
  2961.     say(UPPER);
  2962. }
  2963.  
  2964. MODULE void phase1(void)
  2965. {   SLONG besthero = -1,
  2966.           glory,
  2967.           whichhero,
  2968.           whichjarl,
  2969.           whichmonster,
  2970.           whichorder;
  2971.     FLAG  done;
  2972.  
  2973.    /* "1. MOVEMENT. All heroes and jarls move. The hero with the most
  2974.         glory and his or her jarls move first. In cases of ties the heroes
  2975.         roll dice to see who goes first, with the highest roll going
  2976.         first.
  2977.  
  2978.         A counter may move as many areas as its movement factor. Each area
  2979.         is defined by colour or, in the case of sea areas, by dividing
  2980.         lines. Counters may move and remain in sea areas just as if they
  2981.         were on land. There is no difference between land movement and sea
  2982.         movement." */
  2983.  
  2984.     for (whichhero = 0; whichhero <= HEROES; whichhero++)
  2985.     {   hero[whichhero].moved  =
  2986.         hero[whichhero].hagall =
  2987.         hero[whichhero].routed = FALSE;
  2988.     }
  2989.     for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
  2990.     {   jarl[whichjarl].hagall =
  2991.         jarl[whichjarl].routed = FALSE;
  2992.     }
  2993.     for (whichmonster = 0; whichmonster <= MONSTERS; whichmonster++)
  2994.     {   monster[whichmonster].hagall = FALSE;
  2995.     }
  2996.  
  2997.     for (whichorder = 0; whichorder <= HEROES; whichorder++)
  2998.     {   glory = -1;
  2999.         done = TRUE;
  3000.         for (whichhero = 0; whichhero <= HEROES; whichhero++)
  3001.         {   if (hero[whichhero].alive && !hero[whichhero].moved)
  3002.             {   done = FALSE;
  3003.                 if
  3004.                 (   hero[whichhero].glory > glory
  3005.                  || (hero[whichhero].glory == glory && !(rand() % 2))
  3006.                 )
  3007.                 {   besthero = whichhero;
  3008.                     glory    = hero[whichhero].glory;
  3009.         }   }   }
  3010.         if (done)
  3011.         {   order[whichorder] = -1;
  3012.         } else
  3013.         {   order[whichorder] = besthero;
  3014.             hero[besthero].moved = TRUE;
  3015.     }   }
  3016.  
  3017.     for (whichorder = 0; whichorder <= HEROES; whichorder++)
  3018.     {   if (order[whichorder] == -1)
  3019.         {   break;
  3020.         } else
  3021.         {   move(order[whichorder]);
  3022.     }   }
  3023.  
  3024.     for (whichhero = 0; whichhero <= HEROES; whichhero++)
  3025.     {   hero[whichhero].sea      = NORMAL;
  3026.         hero[whichhero].loseturn = FALSE;
  3027.     }
  3028.     for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
  3029.     {   jarl[whichjarl].sea      = NORMAL;
  3030.         jarl[whichjarl].loseturn = FALSE;
  3031.     }
  3032.     for (whichmonster = 0; whichmonster <= MONSTERS; whichmonster++)
  3033.     {   monster[whichmonster].sea      = NORMAL;
  3034. }   }
  3035.  
  3036. MODULE void phase2(void)
  3037. {   SLONG whichorder;
  3038.  
  3039.     /* "2. COMBAT AND JARLS. Combat occurs in the same sequence as
  3040.         movement; jarls are recruited after combat.
  3041.  
  3042.         Heroes *must* attack at least one monster (if there is a monster)
  3043.         in the area they are in during the combat portion of the turn. If
  3044.         there is more than one monster they may choose which one they wish
  3045.         to fight. They may attack more than one monster in an area." */
  3046.  
  3047.     for (whichorder = 0; whichorder <= HEROES; whichorder++)
  3048.     {   if (order[whichorder] == -1)
  3049.         {   break;
  3050.         } else
  3051.         {   attack(order[whichorder]);
  3052. }   }   }
  3053.  
  3054. MODULE void attack(SLONG whichhero)
  3055. {   SLONG attackers,
  3056.           countertype = -1,
  3057.           country     = -1,
  3058.           whichattack,
  3059.           whichcountry,
  3060.           whichjarl,
  3061.           whichmonster,
  3062.           whichrivalhero;
  3063.     FLAG  must        = FALSE,
  3064.           ok;
  3065.  
  3066.     if (hero[whichhero].alive)
  3067.     {   for (whichattack = 0; whichattack <= ATTACKS; whichattack++)
  3068.         {   hero[whichhero].attacked[whichattack]   = -1;
  3069.             hero[whichhero].attacktype[whichattack] = -1;
  3070.         }
  3071.         for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
  3072.         {   if (jarl[whichjarl].alive && jarl[whichjarl].hero == whichhero)
  3073.             {   for (whichattack = 0; whichattack <= ATTACKS; whichattack++)
  3074.                 {   jarl[whichjarl].attacked[whichattack]   = -1;
  3075.                     jarl[whichjarl].attacktype[whichattack] = -1;
  3076.         }   }   }
  3077.  
  3078.         for (whichmonster = 0; whichmonster <= MONSTERS; whichmonster++)
  3079.         {   if (monster[whichmonster].alive && monster[whichmonster].where == hero[whichhero].where)
  3080.             {   must = TRUE;
  3081.                 break;
  3082.         }   }
  3083.  
  3084.         if (hero[whichhero].control == HUMAN)
  3085.         {   while(1)
  3086.             {   saywho(HERO, whichhero, TRUE, FALSE);
  3087.                 strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_SELECT_ATTACKERS, "select attackers"));
  3088.                 strcat(saystring, "?");
  3089.                 say(LOWER);
  3090.                 country = getevent(COUNTRY, &countertype);
  3091.  
  3092.                 if (country >= 0)
  3093.                 {   if (hero[whichhero].alive && hero[whichhero].where == country && !hero[whichhero].routed)
  3094.                     {   attackers = 1;
  3095.                         select_hero(whichhero);
  3096.                         hero[whichhero].attacking = TRUE;
  3097.                     } else
  3098.                     {   attackers = 0;
  3099.                     }
  3100.                     for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
  3101.                     {   if (jarl[whichjarl].alive && jarl[whichjarl].where == country && !jarl[whichjarl].routed && jarl[whichjarl].hero == whichhero)
  3102.                         {   attackers++;
  3103.                             select_jarl(whichjarl);
  3104.                             jarl[whichjarl].attacking = TRUE;
  3105.                     }   }
  3106.                     if (attackers)
  3107.                     {   getdefender(whichhero, country);
  3108.                 }   }
  3109.                 elif (country == -3)
  3110.                 {   if (must && !hero[whichhero].routed)
  3111.                     {   // check whether the hero has fought a monster
  3112.                         for (whichattack = 0; whichattack <= ATTACKS; whichattack++)
  3113.                         {   if (hero[whichhero].attacktype[whichattack] == MONSTER)
  3114.                             {   return;
  3115.                         }   }
  3116.                         saywho(HERO, whichhero, TRUE, FALSE);
  3117.                         strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_YOU_MUST_FIGHT_A_MONSTER, "you must fight a monster"));
  3118.                         strcat(saystring, ".");
  3119.                         say(LOWER);
  3120.                         anykey();
  3121.                     } else
  3122.                     {   if (hero[whichhero].attacking)
  3123.                         {   deselect_hero(whichhero, TRUE);
  3124.                         }
  3125.                         for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
  3126.                         {   if (jarl[whichjarl].alive && jarl[whichjarl].attacking)
  3127.                             {   deselect_jarl(whichjarl);
  3128.                         }   }
  3129.                         return;
  3130.         }   }   }   }
  3131.         elif (hero[whichhero].control == AMIGA)
  3132.         {   for (whichcountry = 0; whichcountry <= 65; whichcountry++)
  3133.             {   ok = FALSE;
  3134.                 if (hero[whichhero].alive && !hero[whichhero].routed && hero[whichhero].where == whichcountry)
  3135.                 {   hero[whichhero].attacking = TRUE;
  3136.                     select_hero(whichhero);
  3137.                     ok = TRUE;
  3138.                 }
  3139.                 for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
  3140.                 {   if (jarl[whichjarl].alive && jarl[whichjarl].hero == whichhero && !jarl[whichjarl].routed && jarl[whichjarl].where == whichcountry)
  3141.                     {   jarl[whichjarl].attacking = TRUE;
  3142.                         select_jarl(whichjarl);
  3143.                         ok = TRUE;
  3144.                 }   }
  3145.                 if (ok) // there are friendly counters here
  3146.                 {   // check for possible enemies
  3147.                     for (whichrivalhero = 0; whichrivalhero <= HEROES; whichrivalhero++)
  3148.                     {   if (whichhero != whichrivalhero && hero[whichrivalhero].alive && hero[whichrivalhero].where == whichcountry)
  3149.                         {   amiga_attack(whichhero, HERO, whichrivalhero);
  3150.                     }   }
  3151.                     for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
  3152.                     {   if (jarl[whichjarl].alive && jarl[whichjarl].hero != whichhero && jarl[whichjarl].where == whichcountry)
  3153.                         {   amiga_attack(whichhero, JARL, whichjarl);
  3154.                     }   }
  3155.                     for (whichmonster = 0; whichmonster <= MONSTERS; whichmonster++)
  3156.                     {   if (monster[whichmonster].alive && monster[whichmonster].where == whichcountry)
  3157.                         {   amiga_attack(whichhero, MONSTER, whichmonster);
  3158.                     }   }
  3159.                     if (hero[whichhero].attacking)
  3160.                     {   deselect_hero(whichhero, TRUE);
  3161.                         hero[whichhero].attacking = FALSE;
  3162.                     }
  3163.                     for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
  3164.                     {   if (jarl[whichjarl].attacking)
  3165.                         {   deselect_jarl(whichjarl);
  3166.                             jarl[whichjarl].attacking = FALSE;
  3167.                     }   }
  3168.                     /* if (whichcountry <= 35 && world[whichcountry].hero != whichhero)
  3169.                     {   amiga_attack(whichhero, KINGDOM, whichcountry);
  3170.                     } */
  3171. }   }   }   }   }
  3172.  
  3173. MODULE void newgame(void)
  3174. {   SLONG whichhero, whichjarl, whichmonster, whichcountry, whichslot,
  3175.           whichtreasure, whichsord;
  3176.  
  3177.     OffMenu(MainWindowPtr, FULLMENUNUM(MN_PROJECT, IN_NEW,    NOSUB));
  3178.     OffMenu(MainWindowPtr, FULLMENUNUM(MN_PROJECT, IN_OPEN,   NOSUB));
  3179.     OffMenu(MainWindowPtr, FULLMENUNUM(MN_PROJECT, IN_SAVE,   NOSUB));
  3180.     OffMenu(MainWindowPtr, FULLMENUNUM(MN_PROJECT, IN_SAVEAS, NOSUB));
  3181.  
  3182.     pathname[0] = 0;
  3183.  
  3184.     /* 0. SET UP
  3185.  
  3186.     "Divide the counters into four piles, keeping the heroes separate.
  3187.     The four piles, all face down, should be: monsters of all sorts,
  3188.     jarls, magic weapons [(swords)], and magic treasures.
  3189.  
  3190.     Each player picks a hero counter to represent him or her in the game.
  3191.     Players roll dice if two or more people want the same counter, and
  3192.     high roll chooses first." */
  3193.  
  3194.     reset_images();
  3195.     for (whichhero = 0; whichhero <= HEROES; whichhero++)
  3196.     {   hero[whichhero].strength  = HERO_STRENGTH;
  3197.         hero[whichhero].moves     = HERO_MOVES;
  3198.         hero[whichhero].name      = trueheroname[whichhero];
  3199.         hero[whichhero].attacking =
  3200.         hero[whichhero].defending =
  3201.         hero[whichhero].alive     = FALSE;
  3202.         hero[whichhero].verydead  = TRUE;
  3203.         hero[whichhero].glory     =
  3204.         hero[whichhero].luck      =
  3205.         hero[whichhero].wealth    = 0;
  3206.         remove_hero(whichhero, FALSE);
  3207.     }
  3208.     for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
  3209.     {   jarl[whichjarl].hero      = -1;
  3210.         jarl[whichjarl].wealth    = 0;
  3211.         jarl[whichjarl].attacking =
  3212.         jarl[whichjarl].defending =
  3213.         jarl[whichjarl].alive     =
  3214.         jarl[whichjarl].taken     = FALSE;
  3215.         remove_jarl(whichjarl, FALSE);
  3216.     }
  3217.     for (whichmonster = 0; whichmonster <= MONSTERS; whichmonster++)
  3218.     {   monster[whichmonster].alive = FALSE;
  3219.         monster[whichmonster].taken = FALSE;
  3220.         remove_monster(whichmonster, FALSE);
  3221.     }
  3222.     for (whichtreasure = 0; whichtreasure <= TREASURES; whichtreasure++)
  3223.     {   remove_treasure(whichtreasure, FALSE);
  3224.         treasure[whichtreasure].taken         = FALSE;
  3225.         treasure[whichtreasure].possessor     =
  3226.         treasure[whichtreasure].possessortype =
  3227.         treasure[whichtreasure].where         = -1;
  3228.     }
  3229.     for (whichsord = 0; whichsord <= SORDS; whichsord++)
  3230.     {   remove_sord(whichsord, FALSE);
  3231.         sord[whichsord].taken         = FALSE;
  3232.         sord[whichsord].possessor     =
  3233.         sord[whichsord].possessortype =
  3234.         sord[whichsord].where         = -1;
  3235.     }
  3236.  
  3237.     for (whichcountry = 0; whichcountry <= 65; whichcountry++)
  3238.     {   world[whichcountry].hero = -1;
  3239.         world[whichcountry].is   = FALSE;
  3240.         for (whichslot = 0; whichslot <= SLOTS; whichslot++)
  3241.         {   world[whichcountry].slot[whichslot] = FALSE;
  3242.     }   }
  3243.  
  3244.     SetAPen(MainWindowPtr->RPort, BLACK);
  3245.     RectFill(MainWindowPtr->RPort, 0, 0, SCREENXPIXEL, SCREENYPIXEL);
  3246.     darken();
  3247.     drawmap();
  3248.  
  3249.     /* "Each player then picks a magic sword at random from the face-down
  3250.     pile. Magic swords will not be given out again in the game and so all
  3251.     of the left-over magic swords are put aside until the next game." */
  3252.  
  3253.     for (whichhero = 0; whichhero <= HEROES; whichhero++)
  3254.     {   if (hero[whichhero].control != NONE)
  3255.         {   /* "Heroes begin the game in a randomly determined area (found in the
  3256.             same manner as monsters are placed). This area should be noted on the
  3257.             record sheet, as it is sometimes necessary to know a hero's home
  3258.             country." */
  3259.             newhero(whichhero, TRUE);
  3260.     }   }
  3261.  
  3262.     place_monsters();
  3263.     place_jarls();
  3264.     refreshcounters();
  3265.  
  3266.     turn = 1;
  3267.     faxirides = 3;
  3268. }
  3269.  
  3270. MODULE void clearkybd(void)
  3271. {   struct IntuiMessage* MsgPtr;
  3272.  
  3273.     while (MsgPtr = (struct IntuiMessage *) GT_GetIMsg(MainWindowPtr->UserPort))
  3274.         GT_ReplyIMsg(MsgPtr);
  3275. }
  3276.  
  3277. MODULE void titlescreen(void)
  3278. {   AUTO    FLAG                 done;
  3279.     AUTO    SLONG                whichhero;
  3280.     AUTO    struct IntuiMessage* MsgPtr;
  3281.     AUTO    ULONG                class;
  3282.     AUTO    UWORD                code, qual;
  3283.     AUTO    struct Gadget*       addr;
  3284.     AUTO    struct MenuItem*     ItemPtr;
  3285.  
  3286.     loaded   =
  3287.     gameover = FALSE;
  3288.  
  3289.      OnMenu(MainWindowPtr, FULLMENUNUM(MN_PROJECT, IN_NEW,    NOSUB));
  3290.      OnMenu(MainWindowPtr, FULLMENUNUM(MN_PROJECT, IN_OPEN,   NOSUB));
  3291.     OffMenu(MainWindowPtr, FULLMENUNUM(MN_PROJECT, IN_SAVE,   NOSUB));
  3292.     OffMenu(MainWindowPtr, FULLMENUNUM(MN_PROJECT, IN_SAVEAS, NOSUB));
  3293.  
  3294.     SetAPen(MainWindowPtr->RPort, BLACK);
  3295.     RectFill(MainWindowPtr->RPort, 0, 0, SCREENXPIXEL, SCREENYPIXEL);
  3296.     drawlogo();
  3297.  
  3298.     for (whichhero = 0; whichhero <= HEROES; whichhero++)
  3299.     {   GT_SetGadgetAttrs(CycleGadgetPtr[whichhero], MainWindowPtr, NULL, GA_Disabled, FALSE, TAG_DONE);
  3300.     }
  3301.     GT_SetGadgetAttrs(SpeedGadgetPtr, MainWindowPtr, NULL, GA_Disabled, FALSE, TAG_DONE);
  3302.     RefreshGadgets(SpeedGadgetPtr, MainWindowPtr, NULL);
  3303.     if (speed == 2)
  3304.     {   GT_SetGadgetAttrs(SpeedGadgetPtr, MainWindowPtr, NULL, GTSL_Level, 0, TAG_DONE); // kludgy
  3305.     } else
  3306.     {   GT_SetGadgetAttrs(SpeedGadgetPtr, MainWindowPtr, NULL, GTSL_Level, 4 - speed, TAG_DONE); // kludgy
  3307.     }
  3308.     GT_SetGadgetAttrs(SpeedGadgetPtr, MainWindowPtr, NULL, GTSL_Level, speed, TAG_DONE); // kludgy
  3309.  
  3310.     SetAPen(MainWindowPtr->RPort, WHITE);
  3311.     SetDrMd(MainWindowPtr->RPort, JAM1);
  3312.     for (whichhero = 0; whichhero <= HEROES; whichhero++)
  3313.     {   Move(MainWindowPtr->RPort, 212, 208 + (whichhero * 16)    );
  3314.         Text(MainWindowPtr->RPort, cycleheroname[whichhero], 10);
  3315.         Move(MainWindowPtr->RPort, 212 + (cycleheropos[whichhero] * 8), 208 + (whichhero * 16) + 1);
  3316.         Text(MainWindowPtr->RPort, "_", 1);
  3317.     }
  3318.     if (cliload)
  3319.     {   if (loadgame(FALSE))
  3320.         {   loaded = TRUE;
  3321.         } else
  3322.         {   cliload = FALSE;
  3323.     }   }
  3324.  
  3325.     if (!cliload)
  3326.     {   done = FALSE;
  3327.         do
  3328.         {   while (MsgPtr = (struct IntuiMessage *) GT_GetIMsg(MainWindowPtr->UserPort))
  3329.             {   addr  = (struct Gadget *) MsgPtr->IAddress;
  3330.                 class = MsgPtr->Class;
  3331.                 code  = MsgPtr->Code;
  3332.                 qual  = MsgPtr->Qualifier;
  3333.                 GT_ReplyIMsg(MsgPtr);
  3334.                 switch (class)
  3335.                 {
  3336.                 case IDCMP_RAWKEY:
  3337.                     if (!(qual & IEQUALIFIER_REPEAT))
  3338.                     {   switch (code)
  3339.                         {
  3340.                         case HELP:
  3341.                             helpabout();
  3342.                         break;
  3343.                         default:
  3344.                         break;
  3345.                     }   }
  3346.                 break;
  3347.                 case IDCMP_VANILLAKEY:
  3348.                     code = toupper(code);
  3349.                     switch(code)
  3350.                     {
  3351.                     case ' ':
  3352.                     case 13: // Return or Enter
  3353.                         done = TRUE;
  3354.                     break;
  3355.                     case 27: // Escape
  3356.                         cleanexit(EXIT_SUCCESS);
  3357.                     break;
  3358.                     case '1':
  3359.                     case 'B':
  3360.                         if ((qual & IEQUALIFIER_LSHIFT) || (qual & IEQUALIFIER_RSHIFT))
  3361.                         {   if (hero[0].control == 0)
  3362.                             {   hero[0].control = 2;
  3363.                             } else
  3364.                             {   hero[0].control--;
  3365.                         }   }
  3366.                         else
  3367.                         {   if (hero[0].control == 2)
  3368.                             {   hero[0].control = 0;
  3369.                             } else
  3370.                             {   hero[0].control++;
  3371.                         }   }
  3372.                         GT_SetGadgetAttrs(CycleGadgetPtr[0], MainWindowPtr, NULL, GTCY_Active, hero[0].control, TAG_DONE);
  3373.                     break;
  3374.                     case '!':
  3375.                         if (hero[0].control == 0)
  3376.                         {   hero[0].control = 2;
  3377.                         } else
  3378.                         {   hero[0].control--;
  3379.                         }
  3380.                         GT_SetGadgetAttrs(CycleGadgetPtr[0], MainWindowPtr, NULL, GTCY_Active, hero[0].control, TAG_DONE);
  3381.                     break;
  3382.                     case '2':
  3383.                     case 'U':
  3384.                         if ((qual & IEQUALIFIER_LSHIFT) || (qual & IEQUALIFIER_RSHIFT))
  3385.                         {   if (hero[1].control == 0)
  3386.                             {   hero[1].control = 2;
  3387.                             } else
  3388.                             {   hero[1].control--;
  3389.                         }   }
  3390.                         else
  3391.                         {   if (hero[1].control == 2)
  3392.                             {   hero[1].control = 0;
  3393.                             } else
  3394.                             {   hero[1].control++;
  3395.                         }   }
  3396.                         GT_SetGadgetAttrs(CycleGadgetPtr[1], MainWindowPtr, NULL, GTCY_Active, hero[1].control, TAG_DONE);
  3397.                     break;
  3398.                     case '@':
  3399.                         if (hero[1].control == 0)
  3400.                         {   hero[1].control = 2;
  3401.                         } else
  3402.                         {   hero[1].control--;
  3403.                         }
  3404.                         GT_SetGadgetAttrs(CycleGadgetPtr[1], MainWindowPtr, NULL, GTCY_Active, hero[1].control, TAG_DONE);
  3405.                     break;
  3406. /*                  case ONEKEY_MESSAGE_DELAY:
  3407.                         if ((qual & IEQUALIFIER_LSHIFT) || (qual & IEQUALIFIER_RSHIFT))
  3408.                         {   if (speed > 0)
  3409.                             {   speed--;
  3410.                         }   }
  3411.                         else
  3412.                         {   if (speed < 5)
  3413.                             {   speed++;
  3414.                         }   }
  3415.                         GT_SetGadgetAttrs(SpeedGadgetPtr, MainWindowPtr, NULL, GTSL_Level, speed, TAG_DONE);
  3416.                     break; */
  3417.                     case '3':
  3418.                     case 'E':
  3419.                         if ((qual & IEQUALIFIER_LSHIFT) || (qual & IEQUALIFIER_RSHIFT))
  3420.                         {   if (hero[2].control == 0)
  3421.                             {   hero[2].control = 2;
  3422.                             } else
  3423.                             {   hero[2].control--;
  3424.                         }   }
  3425.                         else
  3426.                         {   if (hero[2].control == 2)
  3427.                             {   hero[2].control = 0;
  3428.                             } else
  3429.                             {   hero[2].control++;
  3430.                         }   }
  3431.                         GT_SetGadgetAttrs(CycleGadgetPtr[2], MainWindowPtr, NULL, GTCY_Active, hero[2].control, TAG_DONE);
  3432.                     break;
  3433.                     case '#':
  3434.                         if (hero[2].control == 0)
  3435.                         {   hero[2].control = 2;
  3436.                         } else
  3437.                         {   hero[2].control--;
  3438.                         }
  3439.                         GT_SetGadgetAttrs(CycleGadgetPtr[2], MainWindowPtr, NULL, GTCY_Active, hero[2].control, TAG_DONE);
  3440.                     break;
  3441.                     case '4':
  3442.                     case 'R':
  3443.                         if ((qual & IEQUALIFIER_LSHIFT) || (qual & IEQUALIFIER_RSHIFT))
  3444.                         {   if (hero[3].control == 0)
  3445.                             {   hero[3].control = 2;
  3446.                             } else
  3447.                             {   hero[3].control--;
  3448.                         }   }
  3449.                         else
  3450.                         {   if (hero[3].control == 2)
  3451.                             {   hero[3].control = 0;
  3452.                             } else
  3453.                             {   hero[3].control++;
  3454.                         }   }
  3455.                         GT_SetGadgetAttrs(CycleGadgetPtr[3], MainWindowPtr, NULL, GTCY_Active, hero[3].control, TAG_DONE);
  3456.                     break;
  3457.                     case '$':
  3458.                         if (hero[3].control == 0)
  3459.                         {   hero[3].control = 2;
  3460.                         } else
  3461.                         {   hero[3].control--;
  3462.                         }
  3463.                         GT_SetGadgetAttrs(CycleGadgetPtr[3], MainWindowPtr, NULL, GTCY_Active, hero[3].control, TAG_DONE);
  3464.                     break;
  3465.                     case '5':
  3466.                     case 'S':
  3467.                         if ((qual & IEQUALIFIER_LSHIFT) || (qual & IEQUALIFIER_RSHIFT))
  3468.                         {   if (hero[4].control == 0)
  3469.                             {   hero[4].control = 2;
  3470.                             } else
  3471.                             {   hero[4].control--;
  3472.                         }   }
  3473.                         else
  3474.                         {   if (hero[4].control == 2)
  3475.                             {   hero[4].control = 0;
  3476.                             } else
  3477.                             {   hero[4].control++;
  3478.                         }   }
  3479.                         GT_SetGadgetAttrs(CycleGadgetPtr[4], MainWindowPtr, NULL, GTCY_Active, hero[4].control, TAG_DONE);
  3480.                     break;
  3481.                     case '%':
  3482.                         if (hero[4].control == 0)
  3483.                         {   hero[4].control = 2;
  3484.                         } else
  3485.                         {   hero[4].control--;
  3486.                         }
  3487.                         GT_SetGadgetAttrs(CycleGadgetPtr[4], MainWindowPtr, NULL, GTCY_Active, hero[4].control, TAG_DONE);
  3488.                     break;
  3489.                     case '6':
  3490.                     case 'T':
  3491.                         if ((qual & IEQUALIFIER_LSHIFT) || (qual & IEQUALIFIER_RSHIFT))
  3492.                         {   if (hero[5].control == 0)
  3493.                             {   hero[5].control = 2;
  3494.                             } else
  3495.                             {   hero[5].control--;
  3496.                         }   }
  3497.                         else
  3498.                         {   if (hero[5].control == 2)
  3499.                             {   hero[5].control = 0;
  3500.                             } else
  3501.                             {   hero[5].control++;
  3502.                         }   }
  3503.                         GT_SetGadgetAttrs(CycleGadgetPtr[5], MainWindowPtr, NULL, GTCY_Active, hero[5].control, TAG_DONE);
  3504.                     break;
  3505.                     case '^':
  3506.                         if (hero[5].control == 0)
  3507.                         {   hero[5].control = 2;
  3508.                         } else
  3509.                         {   hero[5].control--;
  3510.                         }
  3511.                         GT_SetGadgetAttrs(CycleGadgetPtr[5], MainWindowPtr, NULL, GTCY_Active, hero[5].control, TAG_DONE);
  3512.                     break;
  3513.                     default:
  3514.                     break;
  3515.                     }
  3516.                 break;
  3517.                 case IDCMP_MENUPICK:
  3518.                     while (code != MENUNULL)
  3519.                 {   ItemPtr = ItemAddress(MenuPtr, code);
  3520.     
  3521.                         switch (MENUNUM(code))
  3522.                         {
  3523.                         case MN_PROJECT:
  3524.                             switch (ITEMNUM(code))
  3525.                             {
  3526.                             case IN_NEW:
  3527.                                 done = TRUE;
  3528.                             break;
  3529.                             case IN_OPEN:
  3530.                                 if (loadgame(TRUE))
  3531.                                 {   done = TRUE;
  3532.                                     loaded = TRUE;
  3533.                                 }
  3534.                             break;
  3535.                             case IN_QUIT:
  3536.                                 cleanexit(EXIT_SUCCESS);
  3537.                             break;
  3538.                             default:
  3539.                                 // IN_SAVE, IN_SAVEAS
  3540.                             break;
  3541.                             }
  3542.                         break;
  3543.                         case MN_HELP:
  3544.                             switch(ITEMNUM(code))
  3545.                             {
  3546.                             case IN_ABOUT:
  3547.                                 helpabout();
  3548.                             break;
  3549.                             default:
  3550.                             break;
  3551.                             }
  3552.                         break;
  3553.                         default:
  3554.                         break;
  3555.                         }
  3556.                         code = ItemPtr->NextSelect;
  3557.                     }
  3558.                 break;
  3559.                 case IDCMP_MOUSEBUTTONS:
  3560.                     if (code == SELECTDOWN && !(qual & IEQUALIFIER_REPEAT))
  3561.                     {   done = TRUE;
  3562.                     }
  3563.                 break;
  3564.                 case IDCMP_REFRESHWINDOW:
  3565.                     GT_BeginRefresh(MainWindowPtr);
  3566.                     GT_EndRefresh(MainWindowPtr, TRUE);
  3567.                 break;
  3568.                 case IDCMP_GADGETUP:
  3569.                     if (addr == SpeedGadgetPtr)
  3570.                     {   speed = code;
  3571.                     } else
  3572.                     {   for (whichhero = 0; whichhero <= HEROES; whichhero++)
  3573.                         {   if (addr == CycleGadgetPtr[whichhero])
  3574.                             {   hero[whichhero].control = code;
  3575.                                 break;
  3576.                     }   }   }
  3577.                 break;
  3578.                 case IDCMP_CLOSEWINDOW:
  3579.                     cleanexit(EXIT_SUCCESS);
  3580.                 break;
  3581.                 default:
  3582.                     ; /* IDCMP_INTUITICKS */
  3583.                 break;
  3584.             }   }
  3585.             if (done)
  3586.             {   done = FALSE;
  3587.                 for (whichhero = 0; whichhero <= HEROES; whichhero++)
  3588.                 {   if (hero[whichhero].control != NONE)
  3589.                     {   done = TRUE;
  3590.                         break;
  3591.                 }   }
  3592.                 if (!done)
  3593.                 {   ; // DisplayBeep(ScreenPtr); // no heroes active
  3594.             }   }
  3595.         } while (!done);
  3596.     }
  3597.  
  3598.     cliload = FALSE;
  3599.     if (!loaded)
  3600.     {   for (whichhero = 0; whichhero <= HEROES; whichhero++)
  3601.         {   GT_SetGadgetAttrs(CycleGadgetPtr[whichhero], MainWindowPtr, NULL, GA_Disabled, TRUE, TAG_DONE);
  3602.         }
  3603.         GT_SetGadgetAttrs(SpeedGadgetPtr, MainWindowPtr, NULL, GA_Disabled, TRUE, TAG_DONE);
  3604.     }
  3605.  
  3606.     if (speed == 4)
  3607.     {   tickwait = -1;
  3608.     } else
  3609.     {   tickwait = speed * 8;
  3610. }   }
  3611.  
  3612. MODULE void gain(SLONG whichhero, SLONG glory, SLONG luck)
  3613. {   SLONG result;
  3614.  
  3615.     if (hero[whichhero].control == HUMAN)
  3616.     {   saywho(HERO, whichhero, TRUE, FALSE);
  3617.         strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_GAIN, "gain"));
  3618.         strcat(saystring, " ");
  3619.         stcl_d(numberstring, glory);
  3620.         strcat(saystring, numberstring);
  3621.         strcat(saystring, " (");
  3622.         strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_CHAR_GLORY, "G"));
  3623.         strcat(saystring, ")");
  3624.         strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_UNCHAR_GLORY, "lory"));
  3625.         strcat(saystring, " ");
  3626.         strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_OR, "or"));
  3627.         strcat(saystring, " ");
  3628.         stcl_d(numberstring, luck);
  3629.         strcat(saystring, numberstring);
  3630.         strcat(saystring, " (");
  3631.         strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_CHAR_LUCK, "L"));
  3632.         strcat(saystring, ")");
  3633.         strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_UNCHAR_LUCK, "uck"));
  3634.         strcat(saystring, "?");
  3635.         say(LOWER);
  3636.         do
  3637.         {   result = getevent(KEYBOARD, NULL);
  3638.         } while (result != onekey[ONEKEY_GLORY] && result != onekey[ONEKEY_LUCK]);
  3639.         if (result == onekey[ONEKEY_GLORY])
  3640.         {   hero[whichhero].glory += glory;
  3641.         } else
  3642.         {   // assert(result == onekey[ONEKEY_LUCK]);
  3643.             hero[whichhero].luck  += luck;
  3644.     }   }
  3645.     else
  3646.     {   hero[whichhero].luck += luck;
  3647. }   }
  3648.  
  3649. MODULE void move(SLONG whichhero)
  3650. {   SLONG country,
  3651.           decision,
  3652.           freemove,
  3653.           i,
  3654.           movearray[66],
  3655.           moves,
  3656.           oldcountry,
  3657.           stop,
  3658.           whichconnection,
  3659.           whichjarl,
  3660.           whichmove = -1,
  3661.           whichrealmove,
  3662.           whichtreasure,
  3663.           whichsord;
  3664.     FLAG  legal;
  3665.  
  3666. // HEROES
  3667.  
  3668.     if (hero[whichhero].alive)
  3669.     {   select_hero(whichhero);
  3670.         moves = getmoves(HERO, whichhero, FALSE);
  3671.  
  3672.         if (hero[whichhero].control == HUMAN)
  3673.         {   if
  3674.             (   treasure[FREYFAXI].possessortype == HERO
  3675.              && treasure[FREYFAXI].possessor     == whichhero
  3676.             )
  3677.             {   // assert(treasure[FREYFAXI].where == -1);
  3678.                 // assert(faxirides >= 1);
  3679.  
  3680.                 if (ask_faxi(HERO, whichhero))
  3681.                 {   moves = getmoves(HERO, whichhero, TRUE);
  3682.             }   }
  3683.  
  3684.             movearray[0] = hero[whichhero].where;
  3685.             whichrealmove = 1;
  3686.             if (moves >= 1)
  3687.             {   oldcountry = hero[whichhero].where;
  3688.                 whichmove     =
  3689.                 whichrealmove = 1;
  3690.                 freemove = FALSE;
  3691.                 do
  3692.                 {   saywho(HERO, whichhero, FALSE, FALSE);
  3693.                     strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_IN, "in"));
  3694.                     strcat(saystring, " ");
  3695.                     strcat(saystring, world[hero[whichhero].where].name);
  3696.                     strcat(saystring, ", ");
  3697.                     strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_MOVE, "move"));
  3698.                     strcat(saystring, " ");
  3699.                     stcl_d(numberstring, whichmove);
  3700.                     strcat(saystring, numberstring);
  3701.                     strcat(saystring, " ");
  3702.                     strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_OF, "of"));
  3703.                     strcat(saystring, " ");
  3704.                     stcl_d(numberstring, moves);
  3705.                     strcat(saystring, numberstring);
  3706.                     strcat(saystring, "?");
  3707.                     say(LOWER);
  3708.                     do
  3709.                     {   country = getevent(COUNTRY, NULL);
  3710.                     } while ((country < -3 || country > 65) || country == -1);
  3711.                     if (country == -3)
  3712.                     {   break;
  3713.                     } elif (country == -2)
  3714.                     {   whichmove     =
  3715.                         whichrealmove = 1;
  3716.                         unslot_hero(whichhero);
  3717.                         hero[whichhero].where = oldcountry;
  3718.                         move_hero(whichhero, TRUE);
  3719.                         freemove = FALSE;
  3720.                     } else
  3721.                     {   legal = FALSE;
  3722.                         for (whichconnection = 0; whichconnection <= CONNECTIONS; whichconnection++)
  3723.                         {   if (world[hero[whichhero].where].connection[whichconnection] == country)
  3724.                             {   legal = TRUE;
  3725.                                 break; // for speed
  3726.                         }   }
  3727.                         if (legal)
  3728.                         {   if
  3729.                             (   hero[whichhero].sea == BAD
  3730.                              && (   world[country].type == SEA
  3731.                                  || world[country].type == ISLE
  3732.                             )   )
  3733.                             {   legal = FALSE;
  3734.                                 saywho(HERO, whichhero, FALSE, FALSE);
  3735.                                 strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_M_N_T_B_S_T_T, "may not travel by sea this turn"));
  3736.                                 strcat(saystring, ".");
  3737.                                 say(LOWER);
  3738.                                 anykey();
  3739.                         }   }
  3740.                         if (legal)
  3741.                         {   unslot_hero(whichhero);
  3742.                             hero[whichhero].where = country;
  3743.                             move_hero(whichhero, TRUE);
  3744.                             if (whichrealmove <= 65)
  3745.                             {    movearray[whichrealmove++] = country;
  3746.                             }
  3747.                             if (hero[whichhero].sea == GOOD)
  3748.                             {   if (!freemove)
  3749.                                 {   if
  3750.                                     (   world[hero[whichhero].where].type == SEA
  3751.                                      || world[hero[whichhero].where].type == ISLE
  3752.                                     )
  3753.                                     {   freemove = TRUE;
  3754.                                     }
  3755.                                     whichmove++;
  3756.                                 } else
  3757.                                 {   if
  3758.                                     (   world[hero[whichhero].where].type == LAND
  3759.                                     )
  3760.                                     {   freemove = FALSE;
  3761.                                         whichmove++;
  3762.                             }   }   }
  3763.                             else
  3764.                             {   whichmove++;
  3765.                         }   }
  3766.                         else
  3767.                         {   ; // DisplayBeep(ScreenPtr);
  3768.                     }   }
  3769.                 } while (whichmove <= moves);
  3770.             }
  3771.  
  3772. /* We ask instead of automatically taking because theoretically a hero
  3773. might want to pass on the opportunity, so he can allow one of his jarls
  3774. in the same square to take the treasure. */
  3775.  
  3776.             for (i = 0; i < whichrealmove; i++)
  3777.             {   for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
  3778.                 {   if (movearray[i] == jarl[whichjarl].where && jarl[whichjarl].hero == whichhero)
  3779.                     {   // hero moved past jarl during move
  3780.                         hero[whichhero].wealth += jarl[whichjarl].wealth;
  3781.                         jarl[whichjarl].wealth = 0;
  3782.             }   }   }
  3783.  
  3784.             for (whichtreasure = 0; whichtreasure <= TREASURES; whichtreasure++)
  3785.             {   if (treasure[whichtreasure].possessortype == KINGDOM && treasure[whichtreasure].where == hero[whichhero].where)
  3786.                 {   // assert(treasure[whichtreasure].possessor = -1);
  3787.  
  3788.                     asktreasure(HERO, whichhero, whichtreasure);
  3789.             }   }
  3790.  
  3791.             if (needsord(HERO, whichhero))
  3792.             {   for (whichsord = 0; whichsord <= SORDS; whichsord++)
  3793.                 {   if (sord[whichsord].possessortype == KINGDOM && sord[whichsord].where == hero[whichhero].where)
  3794.                     {   // assert(sord[whichsord].possessor = -1);
  3795.                         if (asksord(HERO, whichhero, whichsord))
  3796.                         {   break;
  3797.             }   }   }   }
  3798.  
  3799.             if
  3800.             (   treasure[BROSUNGNECKLACE].possessortype == HERO
  3801.              && treasure[BROSUNGNECKLACE].possessor == whichhero
  3802.             )
  3803.             {   brosung(HERO, whichhero);
  3804.         }   }
  3805.         else
  3806.         {   // assert(hero[whichhero].control == AMIGA);
  3807.  
  3808.             movearray[0] = hero[whichhero].where;
  3809.             whichrealmove = 1;
  3810.             if (moves >= 1)
  3811.             {   saywho(HERO, whichhero, FALSE, FALSE);
  3812.                 strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_IS_MOVING, "is moving"));
  3813.                 strcat(saystring, "...");
  3814.                 say(LOWER);
  3815.                 freemove = FALSE;
  3816.  
  3817.                 if
  3818.                 (   hero[whichhero].wounded
  3819.                  && (   hero[whichhero].rune == ING
  3820.                      || hero[whichhero].where == hero[whichhero].homewhere
  3821.                 )   )
  3822.                 {   stop = TRUE;
  3823.                 } else
  3824.                 {   stop = assess(HERO, hero[whichhero].where);
  3825.                 }
  3826.  
  3827.                 for (whichmove = 1; whichmove <= moves; whichmove++)
  3828.                 {   if (!stop)
  3829.                     {   stop = assess(HERO, whichhero);
  3830.                     }
  3831.                     if (stop)
  3832.                     {   break;
  3833.                     }
  3834.  
  3835.                     do
  3836.                     {   decision = rand() % (CONNECTIONS + 1);
  3837.                     } while (world[hero[whichhero].where].connection[decision] == -1);
  3838.  
  3839.                     if
  3840.                     (   hero[whichhero].sea == BAD
  3841.                      && (   world[world[hero[whichhero].where].connection[decision]].type == SEA
  3842.                          || world[world[hero[whichhero].where].connection[decision]].type == ISLE
  3843.                     )   )
  3844.                     {   whichmove--;
  3845.                     } else
  3846.                     {   unslot_hero(whichhero);
  3847.                         hero[whichhero].where = world[hero[whichhero].where].connection[decision];
  3848.                         move_hero(whichhero, TRUE);
  3849.                         if (whichrealmove <= 65)
  3850.                         {   movearray[whichrealmove++] = hero[whichhero].where;
  3851.                         }
  3852.  
  3853.                         if (hero[whichhero].sea == GOOD)
  3854.                         {   if (!freemove)
  3855.                             {   if
  3856.                                 (   world[hero[whichhero].where].type == SEA
  3857.                                  || world[hero[whichhero].where].type == ISLE
  3858.                                 )
  3859.                                 {   freemove = TRUE;
  3860.                             }   }
  3861.                             else
  3862.                             {   if
  3863.                                 (   world[hero[whichhero].where].type == LAND
  3864.                                 )
  3865.                                 {   freemove = FALSE;
  3866.                                 } else
  3867.                                 {   whichmove--;
  3868.             }   }   }   }   }   }
  3869.  
  3870.             for (i = 0; i < whichrealmove; i++)
  3871.             {   for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
  3872.                 {   if (movearray[i] == jarl[whichjarl].where && jarl[whichjarl].hero == whichhero)
  3873.                     {   // hero moved past jarl during move
  3874.                         hero[whichhero].wealth += jarl[whichjarl].wealth;
  3875.                         jarl[whichjarl].wealth = 0;
  3876.             }   }   }
  3877.  
  3878.             // Amiga always takes whatever it can.
  3879.             for (whichtreasure = 0; whichtreasure <= TREASURES; whichtreasure++)
  3880.             {   if (treasure[whichtreasure].possessortype == KINGDOM && treasure[whichtreasure].where == hero[whichhero].where)
  3881.                 {   // assert(treasure[whichtreasure].possessor = -1);
  3882.  
  3883.                     remove_treasure(whichtreasure, TRUE);
  3884.                     treasure[whichtreasure].possessortype = HERO;
  3885.                     treasure[whichtreasure].possessor     = whichhero;
  3886.                     treasure[whichtreasure].where         = -1;
  3887.  
  3888.                     saywho(HERO, whichhero, FALSE, FALSE);
  3889.                     strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_TAKES_THE, "takes the"));
  3890.                     strcat(saystring, " ");
  3891.                     strcat(saystring, treasure[whichtreasure].name);
  3892.                     strcat(saystring, ".");
  3893.                     say(LOWER);
  3894.                     anykey();
  3895.             }   }
  3896.  
  3897.             if (needsord(HERO, whichhero))
  3898.             {   for (whichsord = 0; whichsord <= SORDS; whichsord++)
  3899.                 {   if (sord[whichsord].possessortype == KINGDOM && sord[whichsord].where == hero[whichhero].where)
  3900.                     {   // assert(sord[whichsord].possessor = -1);
  3901.  
  3902.                         remove_sord(whichsord, TRUE);
  3903.                         sord[whichsord].possessortype = HERO;
  3904.                         sord[whichsord].possessor     = whichhero;
  3905.                         sord[whichsord].where         = -1;
  3906.  
  3907.                         saywho(HERO, whichhero, FALSE, FALSE);
  3908.                         strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_TAKES_SWORD, "takes sword"));
  3909.                         strcat(saystring, " ");
  3910.                         strcat(saystring, sord[whichsord].name);
  3911.                         strcat(saystring, ".");
  3912.                         say(LOWER);
  3913.                         anykey();
  3914.  
  3915.                         break;
  3916.         }   }   }   }
  3917.  
  3918.         // check healing
  3919.  
  3920.         if
  3921.         (   whichmove == 1
  3922.          && hero[whichhero].wounded
  3923.          && (   hero[whichhero].where == hero[whichhero].homewhere
  3924.              || hero[whichhero].rune == ING
  3925.         )   )
  3926.         {   hero[whichhero].wounded = FALSE;
  3927.             saywho(HERO, whichhero, FALSE, FALSE);
  3928.             strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_HEALS, "heals"));
  3929.             strcat(saystring, ".");
  3930.             say(LOWER);
  3931.             anykey();
  3932.         }
  3933.         deselect_hero(whichhero, TRUE);
  3934.  
  3935.         // JARLS
  3936.  
  3937.         for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
  3938.         {   if (jarl[whichjarl].alive && jarl[whichjarl].hero == whichhero)
  3939.             {   select_jarl(whichjarl);
  3940.                 moves = getmoves(JARL, whichjarl, FALSE);
  3941.                 if (hero[whichhero].control == HUMAN)
  3942.                 {   if
  3943.                     (   treasure[FREYFAXI].possessortype == JARL
  3944.                      && treasure[FREYFAXI].possessor     == whichjarl
  3945.                     )
  3946.                     {   // assert(treasure[FREYFAXI].where == -1);
  3947.                         // assert(faxirides >= 1);
  3948.  
  3949.                         if (ask_faxi(JARL, whichjarl))
  3950.                         {   moves = getmoves(JARL, whichjarl, TRUE);
  3951.                     }   }
  3952.  
  3953.                     movearray[0] = jarl[whichjarl].where;
  3954.                     whichmove = 1;
  3955.                     if (moves >= 1)
  3956.                     {   oldcountry = jarl[whichjarl].where;
  3957.                         do
  3958.                         {   saywho(JARL, whichjarl, FALSE, FALSE);
  3959.                             strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_IN, "in"));
  3960.                             strcat(saystring, " ");
  3961.                             strcat(saystring, world[jarl[whichjarl].where].name);
  3962.                             strcat(saystring, ", ");
  3963.                             strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_MOVE, "move"));
  3964.                             strcat(saystring, " ");
  3965.                             stcl_d(numberstring, whichmove);
  3966.                             strcat(saystring, numberstring);
  3967.                             strcat(saystring, " ");
  3968.                             strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_OF, "of"));
  3969.                             strcat(saystring, " ");
  3970.                             stcl_d(numberstring, moves);
  3971.                             strcat(saystring, numberstring);
  3972.                             strcat(saystring, "?");
  3973.                             say(LOWER);
  3974.                             do
  3975.                             {   country = getevent(COUNTRY, NULL);
  3976.                             } while ((country < -3 || country > 65) || country == -1);
  3977.                             if (country == -3)
  3978.                             {   break;
  3979.                             } elif (country == -2)
  3980.                             {   whichmove = 1;
  3981.                                 unslot_jarl(whichjarl);
  3982.                                 jarl[whichjarl].where = oldcountry;
  3983.                                 move_jarl(whichjarl, TRUE);
  3984.                             } else
  3985.                             {   legal = FALSE;
  3986.                                 for (whichconnection = 0; whichconnection <= CONNECTIONS; whichconnection++)
  3987.                                 {   if (world[jarl[whichjarl].where].connection[whichconnection] == country)
  3988.                                     {   legal = TRUE;
  3989.                                         break; // for speed
  3990.                                 }   }
  3991.                                 if (legal)
  3992.                                 {   if
  3993.                                     (   jarl[whichjarl].sea == BAD
  3994.                                      && (   world[country].type == SEA
  3995.                                          || world[country].type == ISLE
  3996.                                     )   )
  3997.                                     {   legal = FALSE;
  3998.                                         saywho(JARL, whichjarl, FALSE, FALSE);
  3999.                                         strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_M_N_T_B_S_T_T, "may not travel by sea this turn"));
  4000.                                         strcat(saystring, ".");
  4001.                                         say(LOWER);
  4002.                                         anykey();
  4003.                                 }   }
  4004.                                 if (legal)
  4005.                                 {   unslot_jarl(whichjarl);
  4006.                                     jarl[whichjarl].where = country;
  4007.                                     move_jarl(whichjarl, TRUE);
  4008.                                     movearray[whichmove] = country;
  4009.                                     whichmove++;
  4010.                                 } else
  4011.                                 {   ; // DisplayBeep(ScreenPtr);
  4012.                             }   }
  4013.                         } while (whichmove <= moves);
  4014.                     }
  4015.  
  4016.                     for (i = 0; i < whichmove; i++)
  4017.                     {   if (movearray[i] == hero[whichhero].where)
  4018.                         {   // jarl moved past hero during move
  4019.                             hero[whichhero].wealth += jarl[whichjarl].wealth;
  4020.                             jarl[whichjarl].wealth = 0;
  4021.                     }   }
  4022.  
  4023.                     for (whichtreasure = 0; whichtreasure <= TREASURES; whichtreasure++)
  4024.                     {   if (treasure[whichtreasure].possessortype == KINGDOM && treasure[whichtreasure].where == jarl[whichjarl].where)
  4025.                         {   // assert(treasure[whichtreasure].possessor = -1);
  4026.  
  4027.                             asktreasure(JARL, whichjarl, whichtreasure);
  4028.                     }   }
  4029.  
  4030.                     if (needsord(JARL, whichjarl))
  4031.                     {   for (whichsord = 0; whichsord <= SORDS; whichsord++)
  4032.                         {   if (sord[whichsord].possessortype == KINGDOM && sord[whichsord].where == jarl[whichjarl].where)
  4033.                             {   // assert(sord[whichsord].possessor = -1);
  4034.  
  4035.                                 if (asksord(JARL, whichjarl, whichsord))
  4036.                                 {   break;
  4037.                     }   }   }   }
  4038.                     if
  4039.                     (   treasure[BROSUNGNECKLACE].possessortype == JARL
  4040.                      && treasure[BROSUNGNECKLACE].possessor == whichjarl
  4041.                     )
  4042.                     {   brosung(JARL, whichjarl);
  4043.                 }   }
  4044.                 elif (hero[whichhero].control == AMIGA)
  4045.                 {   saywho(JARL, whichjarl, FALSE, FALSE);
  4046.                     strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_IS_MOVING, "is moving"));
  4047.                     strcat(saystring, "...");
  4048.                     say(LOWER);
  4049.  
  4050.                     movearray[0] = jarl[whichjarl].where;
  4051.                     whichmove = 1;
  4052.                     if (moves >= 1)
  4053.                     {   for (whichmove = 1; whichmove <= moves; whichmove++)
  4054.                         {   stop = assess(JARL, whichjarl);
  4055.                             if (stop)
  4056.                             {   break;
  4057.                             }
  4058.  
  4059.                             do
  4060.                             {   decision = rand() % (CONNECTIONS + 1);
  4061.                             } while (world[jarl[whichjarl].where].connection[decision] == -1);
  4062.  
  4063.                             if
  4064.                             (   jarl[whichjarl].sea == BAD
  4065.                              && (   world[world[jarl[whichjarl].where].connection[decision]].type == SEA
  4066.                                  || world[world[jarl[whichjarl].where].connection[decision]].type == ISLE
  4067.                             )   )
  4068.                             {   whichmove--;
  4069.                             } else
  4070.                             {   unslot_jarl(whichjarl);
  4071.                                 jarl[whichjarl].where = world[jarl[whichjarl].where].connection[decision];
  4072.                                 move_jarl(whichjarl, TRUE);
  4073.                                 movearray[whichmove] = jarl[whichjarl].where;
  4074.                     }   }   }
  4075.  
  4076.                     for (i = 0; i < whichmove; i++)
  4077.                     {   if (movearray[i] == hero[whichhero].where)
  4078.                         {   // jarl moved past hero during move
  4079.                             hero[whichhero].wealth += jarl[whichjarl].wealth;
  4080.                             jarl[whichjarl].wealth = 0;
  4081.                     }   }
  4082.  
  4083.                     // Amiga always takes whatever it can.
  4084.                     for (whichtreasure = 0; whichtreasure <= TREASURES; whichtreasure++)
  4085.                     {   if (treasure[whichtreasure].possessortype == KINGDOM && treasure[whichtreasure].where == jarl[whichjarl].where)
  4086.                         {   // assert(treasure[whichtreasure].possessor = -1);
  4087.  
  4088.                             remove_treasure(whichtreasure, TRUE);
  4089.                             treasure[whichtreasure].possessortype = JARL;
  4090.                             treasure[whichtreasure].possessor     = whichjarl;
  4091.                             treasure[whichtreasure].where         = -1;
  4092.  
  4093.                             saywho(JARL, whichjarl, FALSE, FALSE);
  4094.                             strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_TAKES_THE, "takes the"));
  4095.                             strcat(saystring, " ");
  4096.                             strcat(saystring, treasure[whichtreasure].name);
  4097.                             strcat(saystring, ".");
  4098.                             say(LOWER);
  4099.                             anykey();
  4100.                     }   }
  4101.  
  4102.                     if (needsord(JARL, whichjarl))
  4103.                     {   for (whichsord = 0; whichsord <= SORDS; whichsord++)
  4104.                         {   if (sord[whichsord].possessortype == KINGDOM && sord[whichsord].where == jarl[whichjarl].where)
  4105.                             {   // assert(sord[whichsord].possessor = -1);
  4106.             
  4107.                                 remove_sord(whichsord, TRUE);
  4108.                                 sord[whichsord].possessortype = HERO;
  4109.                                 sord[whichsord].possessor     = whichhero;
  4110.                                 sord[whichsord].where         = -1;
  4111.  
  4112.                                 saywho(JARL, whichjarl, FALSE, FALSE);
  4113.                                 strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_TAKES_SWORD, "takes sword"));
  4114.                                 strcat(saystring, " ");
  4115.                                 strcat(saystring, sord[whichsord].name);
  4116.                                 strcat(saystring, ".");
  4117.                                 say(LOWER);
  4118.                                 anykey();
  4119.  
  4120.                                 break;
  4121.                 }   }   }   }
  4122.                 deselect_jarl(whichjarl);
  4123. }   }   }   }
  4124.  
  4125. MODULE void helpabout(void)
  4126. {   SBYTE                line;
  4127.     FLAG                 done          = FALSE;
  4128.     ULONG                class;
  4129.     UWORD                code, qual;
  4130.     struct IntuiMessage* MsgPtr;
  4131.  
  4132.     if (!(HelpWindowPtr = (struct Window *) OpenWindowTags(NULL,
  4133.         WA_Left,          (SCREENXPIXEL / 2) - (ABOUTXPIXEL / 2),
  4134.         WA_Top,           (SCREENYPIXEL / 2) - (ABOUTYPIXEL / 2),
  4135.         WA_Width,         ABOUTXPIXEL,
  4136.         WA_Height,        ABOUTYPIXEL,
  4137.         WA_IDCMP,         IDCMP_CLOSEWINDOW | IDCMP_RAWKEY,
  4138.         WA_Title,         abouttitle,
  4139.         WA_Gadgets,       NULL,
  4140.         WA_CustomScreen,  ScreenPtr,
  4141.         WA_DragBar,       TRUE,
  4142.         WA_CloseGadget,   TRUE,
  4143.         WA_NoCareRefresh, TRUE,
  4144.         WA_Activate,      TRUE,
  4145.     TAG_DONE))
  4146.     )
  4147.     {   DisplayAlert(AT_Recovery, "\0\20\20Saga: Can't open About... window!\0", 24);
  4148.         cleanexit(EXIT_FAILURE);
  4149.     } else
  4150.     {   SetAPen(HelpWindowPtr->RPort, LIGHTGREY);
  4151.         RectFill(HelpWindowPtr->RPort, 8, 13, ABOUTXPIXEL - 10, ABOUTYPIXEL - 6);
  4152.         SetAPen(HelpWindowPtr->RPort, BLACK);
  4153.         SetDrMd(HelpWindowPtr->RPort, JAM1);
  4154.         for (line = 0; line <= ABOUTLINES; line++)
  4155.         {   Move(HelpWindowPtr->RPort, about[line].x, about[line].y);
  4156.             Text(HelpWindowPtr->RPort, about[line].text, (SBYTE) strlen(about[line].text));
  4157.         }
  4158.  
  4159.         DrawBevelBox(HelpWindowPtr->RPort, 16, 20, 44 + 4, 38 + 4, GT_VisualInfo, VisualInfoPtr, GTBB_Recessed, TRUE, TAG_END);
  4160.  
  4161.         drawabout();
  4162.  
  4163.         while(!done)
  4164.         {   Wait(1L << HelpWindowPtr->UserPort->mp_SigBit);
  4165.             while (MsgPtr = (struct IntuiMessage *) GetMsg(HelpWindowPtr->UserPort))
  4166.             {   class  = MsgPtr->Class;
  4167.                 code   = MsgPtr->Code;
  4168.                 qual   = MsgPtr->Qualifier;
  4169.                 ReplyMsg((struct Message *) MsgPtr);
  4170.                 switch(class)
  4171.                 {
  4172.                 case IDCMP_CLOSEWINDOW:
  4173.                     done = TRUE;
  4174.                 break;
  4175.                 case IDCMP_RAWKEY:
  4176.                     if (!(qual & IEQUALIFIER_REPEAT) && code < KEYUP && (code < FIRSTQUALIFIER || code > LASTQUALIFIER))
  4177.                     {   done = TRUE;
  4178.                     }
  4179.                 break;
  4180.                 default:
  4181.                 break;
  4182.         }   }   }
  4183.         CloseWindow(HelpWindowPtr);
  4184.         HelpWindowPtr = NULL;
  4185.         clearkybd();
  4186. }   }
  4187.  
  4188. MODULE void resettime(void)
  4189. {   struct timerequest* TimerIORequestPtr;
  4190.     struct timeval      timeval;
  4191.  
  4192.     if (!(TimerIORequestPtr = (struct timerequest *) AllocVec(sizeof(struct timerequest), MEMF_PUBLIC | MEMF_CLEAR)))
  4193.     {   DisplayAlert(AT_Recovery, "\0\20\20Saga: Out of memory!\0", 24);
  4194.         cleanexit(EXIT_FAILURE);
  4195.     }
  4196.     if (OpenDevice(TIMERNAME, UNIT_MICROHZ, (struct IORequest *) TimerIORequestPtr, 0))
  4197.     {   FreeVec(TimerIORequestPtr);
  4198.         DisplayAlert(AT_Recovery, "\0\20\20Saga: Can't open timer.device!\0", 24);
  4199.         cleanexit(EXIT_FAILURE);
  4200.     }
  4201.     TimerBase = (struct Library *) TimerIORequestPtr->tr_node.io_Device;
  4202.     GetSysTime(&timeval);
  4203.     srand((UWORD) timeval.tv_micro);
  4204.     // no need to abort timer I/O requests, as we never send any
  4205.     CloseDevice((struct IORequest *) TimerIORequestPtr);
  4206.     FreeVec(TimerIORequestPtr);
  4207. }
  4208.  
  4209. MODULE void anykey(void)
  4210. {   if (tickwait != 0)
  4211.     {   getevent(ANYKEY, NULL);
  4212. }   }
  4213.  
  4214. MODULE SLONG getluck(SLONG whichhero)
  4215. {   SLONG result;
  4216.  
  4217.     while(1)
  4218.     {   do
  4219.         {   result = getevent(KEYBOARD, NULL);
  4220.         } while (result < '0' || result > '9');
  4221.  
  4222.         if (result == '0')
  4223.         {   return(0);
  4224.         } else
  4225.         {   result -= '0';
  4226.         }
  4227.  
  4228.         if (result > hero[whichhero].luck)
  4229.         {   ; // DisplayBeep(ScreenPtr);
  4230.         } else
  4231.         {   hero[whichhero].luck -= result;
  4232.             return(result);
  4233. }   }   }
  4234.  
  4235. MODULE void phase3(void)
  4236. {   FLAG  ok;
  4237.     SBYTE whichhero, whichcountry, whichjarl;
  4238.  
  4239.     for (whichhero = 0; whichhero <= HEROES; whichhero++)
  4240.     {   if (hero[whichhero].control != NONE && !(hero[whichhero].verydead))
  4241.         /* Note that we even do this for dead heroes: they can keep their
  4242.            kingdoms (for now) where they have jarls, as they may be
  4243.            promoting a jarl, in which case they are allowed to keep their
  4244.            kingdoms. */
  4245.         {   for (whichcountry = 0; whichcountry <= 35; whichcountry++)
  4246.             {   if (world[whichcountry].hero == whichhero)
  4247.                 {   // determine whether the hero or one of his jarls is there
  4248.  
  4249.                     ok = FALSE;
  4250.                     if (!world[whichcountry].is)
  4251.                     {   if (hero[whichhero].where == whichcountry)
  4252.                         {   ok = TRUE;
  4253.                             hero[whichhero].wealth += world[whichcountry].tax;
  4254.                             if (hero[whichhero].rune == GEOFU)
  4255.                             {   hero[whichhero].wealth++;
  4256.                         }   }
  4257.                         else
  4258.                         {   for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
  4259.                             {   if
  4260.                                 (   jarl[whichjarl].alive
  4261.                                  && jarl[whichjarl].hero == whichhero
  4262.                                  && jarl[whichjarl].where == whichcountry
  4263.                                 ) // taxes are given to the first friendly jarl found
  4264.                                 {   ok = TRUE;
  4265.                                     jarl[whichjarl].wealth += world[whichcountry].tax;
  4266.                                     if (hero[whichhero].rune == GEOFU)
  4267.                                     {   jarl[whichjarl].wealth++;
  4268.                                     }
  4269.                                     break;
  4270.                     }   }   }   }
  4271.  
  4272.                     if (!ok)
  4273.                     {   world[whichcountry].hero = -1;
  4274.                         darken();
  4275.  
  4276.                         strcpy(saystring, GetCatalogStr(li.li_Catalog, MSG_HERO, "Hero"));
  4277.                         strcat(saystring, " ");
  4278.                         strcat(saystring, hero[whichhero].name);
  4279.                         strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_S_KINGDOM, "'s kingdom"));
  4280.                         strcat(saystring, " ");
  4281.                         strcat(saystring, world[whichcountry].name);
  4282.                         strcat(saystring, " (");
  4283.                         stcl_d(numberstring, world[whichcountry].tax);
  4284.                         strcat(saystring, numberstring);
  4285.                         strcat(saystring, ") ");
  4286.                         strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_HAS_BEEN_OVERRUN, "has been overrun"));
  4287.                         strcat(saystring, ".");
  4288.                         say(LOWER);
  4289.                         anykey();
  4290. }   }   }   }   }   }
  4291.  
  4292. MODULE void gods(SLONG whichhero)
  4293. {   SLONG whichgod, whichprayer, decision;
  4294.     FLAG  heard;
  4295.  
  4296.     whichgod    = rand() % 6;
  4297.     whichprayer = d6();
  4298.  
  4299.     switch(whichgod)
  4300.     {
  4301.     case FREY:
  4302.         strcpy(saystring, "Frey ");
  4303.         heard = FALSE;
  4304.         if (whichprayer <= 4)
  4305.         {   // assert(whichprayer >= 1);
  4306.             hero[whichhero].maidens++;
  4307.  
  4308.             strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_W_S_A_M_T_H_H, "will send a maiden to heal hero"));
  4309.             strcat(saystring, " ");                                    
  4310.             strcat(saystring, hero[whichhero].name);
  4311.             strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_S_NEXT_WOUND, "'s next wound"));
  4312.             strcat(saystring, ".");
  4313.         } else
  4314.         {   // assert(whichprayer == 5 || whichprayer == 6);
  4315.             hero[whichhero].maidens += 2;
  4316.  
  4317.             strcpy(saystring, GetCatalogStr(li.li_Catalog, MSG_W_S_A_M_T_H_H, "will send a maiden to heal hero"));
  4318.             strcat(saystring, " ");
  4319.             strcat(saystring, hero[whichhero].name);
  4320.             strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_S_NEXT_TWO_WOUNDS, "'s next two wounds"));
  4321.             strcat(saystring, ".");
  4322.         }
  4323.     break;
  4324.     case LOKI:
  4325.         strcpy(saystring, "Loki ");
  4326.         heard = FALSE;
  4327.         if (whichprayer <= 3)
  4328.         {   // assert(whichprayer >= 0);
  4329.  
  4330.             hero[whichhero].luck--;
  4331.             if (hero[whichhero].luck < 0)
  4332.             {   hero[whichhero].luck = 0;
  4333.             }
  4334.  
  4335.             strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_S_A_P_O_L_F_H, "steals a point of luck from hero"));
  4336.             strcat(saystring, " ");
  4337.             strcat(saystring, hero[whichhero].name);
  4338.             strcat(saystring, ".");
  4339.         } else
  4340.         {   // assert(whichprayer >= 4 && whichprayer <= 6);
  4341.  
  4342.             hero[whichhero].luck++;
  4343.  
  4344.             strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_GRANTS_HERO, "grants hero"));
  4345.             strcat(saystring, " ");
  4346.             strcat(saystring, hero[whichhero].name);
  4347.             strcat(saystring, " ");                                                        
  4348.             strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_A_P_O_L_F_H_D, "a point of luck for his daring"));
  4349.             strcat(saystring, ".");
  4350.         }
  4351.     break;
  4352.     case NJORD:
  4353.         strcpy(saystring, "Njord ");
  4354.         heard = FALSE;
  4355.         if (whichprayer == 1 || whichprayer == 2)
  4356.         {   hero[whichhero].sea = GOOD;
  4357.  
  4358.             strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_AIDS_HERO, "aids hero"));
  4359.             strcat(saystring, " ");
  4360.             strcat(saystring, hero[whichhero].name);
  4361.             strcat(saystring, " ");
  4362.             strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_TO_MOVE_BY_SEA_NEXT_TURN, "to move by sea next turn"));
  4363.             strcat(saystring, ".");
  4364.         } elif (whichprayer == 3 || whichprayer == 4)
  4365.         {   decision = d6();
  4366.             hero[whichhero].wealth += decision;
  4367.  
  4368.             strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_GIVES, "gives"));
  4369.             strcat(saystring, " ");
  4370.             stcl_d(numberstring, decision);
  4371.             strcat(saystring, numberstring);
  4372.             strcat(saystring, " ");
  4373.             strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_GOLDEN_MARKS_TO_HERO, "golden marks to hero"));
  4374.             strcat(saystring, " ");
  4375.             strcat(saystring, hero[whichhero].name);
  4376.             strcat(saystring, " ");
  4377.             strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_AS_A_GIFT, "as a gift"));
  4378.             strcat(saystring, ".");
  4379.         } elif (whichprayer == 5)
  4380.         {   decision = d6();
  4381.             if (decision > hero[whichhero].wealth)
  4382.             {   decision = hero[whichhero].wealth;
  4383.             }
  4384.             hero[whichhero].wealth -= decision;
  4385.  
  4386.             strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_TAKES, "takes"));
  4387.             strcat(saystring, " ");
  4388.             stcl_d(numberstring, decision);
  4389.             strcat(saystring, numberstring);
  4390.             strcat(saystring, " ");
  4391.             strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_GOLDEN_MARKS_FROM_HERO, "golden marks from hero"));
  4392.             strcat(saystring, " ");
  4393.             strcat(saystring, hero[whichhero].name);
  4394.             strcat(saystring, " ");
  4395.             strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_AS_DUE_TRIBUTE, "as due tribute"));
  4396.             strcat(saystring, ".");
  4397.         } else
  4398.         {   // assert(whichprayer == 6);
  4399.             hero[whichhero].sea = BAD;
  4400.  
  4401.             strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_PREVENTS_HERO, "prevents hero"));
  4402.             strcat(saystring, " ");
  4403.             strcat(saystring, hero[whichhero].name);
  4404.             strcat(saystring, " ");
  4405.             strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_F_T_B_S_N_T, "from travelling by sea next turn"));
  4406.             strcat(saystring, ".");
  4407.         }
  4408.     break;
  4409.     case ODIN:
  4410.         hero[whichhero].god = ODIN;
  4411.         heard = TRUE;
  4412.         strcpy(saystring, "Odin ");
  4413.     break;
  4414.     case THOR:
  4415.         hero[whichhero].god = THOR;
  4416.         heard = TRUE;
  4417.         strcpy(saystring, "Thor ");
  4418.     break;
  4419.     case TYR:
  4420.         hero[whichhero].god = TYR;
  4421.         heard = TRUE;
  4422.         strcpy(saystring, "Tyr ");
  4423.     break;
  4424.     default:
  4425.     break;
  4426.     }
  4427.     if (heard)
  4428.     {   strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_HEARD_THE_PRAYER_OF_HERO, "heard the prayer of hero"));
  4429.         strcat(saystring, " ");
  4430.         strcat(saystring, hero[whichhero].name);
  4431.         strcat(saystring, ".");
  4432.     }
  4433.     say(LOWER);
  4434.     anykey();
  4435. }
  4436.  
  4437. MODULE FLAG loadgame(FLAG aslwindow)
  4438. {   SLONG offset = 12, whichhero, whichjarl, whichmonster, whichcountry,
  4439.           whichslot, whichtreasure, whichsord;
  4440.     TEXT  newpathname[255];
  4441.     BPTR  FileHandle /* = NULL */ ;
  4442.     FLAG  ok;
  4443.  
  4444.     if (aslwindow)
  4445.     {   if
  4446.         (   AslRequestTags
  4447.             (    ASLRqPtr,
  4448.                  ASL_Hail, GetCatalogStr(li.li_Catalog, MSG_LOAD_GAME, "Load Game"),
  4449.                  ASL_FuncFlags, FILF_PATGAD,
  4450.                  TAG_DONE
  4451.             )
  4452.          && *(ASLRqPtr->rf_File)
  4453.         )
  4454.         {   strcpy(newpathname, ASLRqPtr->rf_Dir);
  4455.             AddPart(newpathname, ASLRqPtr->rf_File, 254);
  4456.             ok = TRUE;
  4457.         } else
  4458.         {   ok = FALSE;
  4459.     }   }
  4460.     else
  4461.     {   ok = TRUE;
  4462.         strcpy(newpathname, pathname);
  4463.     }
  4464.  
  4465.     // 'SAGA 1.0' fieldsets are 544 bytes long, plus the version string.
  4466.  
  4467.     if (ok)
  4468.     {   strcpy(saystring, GetCatalogStr(li.li_Catalog, MSG_LOADING, "Loading"));
  4469.         strcat(saystring, " ");
  4470.         strcat(saystring, newpathname);
  4471.         strcat(saystring, "...");
  4472.         say(LOWER);
  4473.  
  4474.         if (!(FileHandle = Open(newpathname, MODE_OLDFILE)))
  4475.         {   strcpy(saystring, GetCatalogStr(li.li_Catalog, MSG_CANT_OPEN, "Can't open"));
  4476.             strcat(saystring, " ");
  4477.             strcat(saystring, newpathname);
  4478.             strcat(saystring, " ");
  4479.             strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_FOR_READING, "for reading"));
  4480.             strcat(saystring, "!");
  4481.             say(LOWER);
  4482.             return(FALSE);
  4483.         }
  4484.  
  4485.         // read file
  4486.         if (Read(FileHandle, IOBuffer, 544) != 544)
  4487.         {   Close(FileHandle);
  4488.             // FileHandle = NULL;
  4489.             strcpy(saystring, GetCatalogStr(li.li_Catalog, MSG_CANT_READ_FROM, "Can't read from"));
  4490.             strcat(saystring, " ");
  4491.             strcat(saystring, newpathname);
  4492.             strcat(saystring, "!");
  4493.             say(LOWER);
  4494.             return(FALSE);
  4495.         }
  4496.  
  4497.         if (strcmp(IOBuffer, "SAGA 1.0 "))
  4498.         {   Close(FileHandle);
  4499.             // FileHandle = NULL;
  4500.             strcpy(saystring, newpathname);
  4501.             strcat(saystring, " ");
  4502.             strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_I_N_A_V_S_G_F, "is not a valid saved game file"));
  4503.             strcat(saystring, "!");
  4504.             say(LOWER);
  4505.             return(FALSE);
  4506.         }
  4507.         turn      = (SLONG) ((SBYTE) IOBuffer[10]);
  4508.         faxirides = (SLONG) ((SBYTE) IOBuffer[11]);
  4509.  
  4510.         for (whichhero = 0; whichhero <= HEROES; whichhero++)
  4511.         {   hero[whichhero].control   = (SLONG) ((SBYTE) IOBuffer[offset++] );
  4512.             hero[whichhero].alive     = (FLAG)  ((SBYTE) IOBuffer[offset++] );
  4513.             hero[whichhero].verydead  = (FLAG)  ((SBYTE) IOBuffer[offset++] );
  4514.             hero[whichhero].moves     = (SLONG) ((SBYTE) IOBuffer[offset++] );
  4515.             hero[whichhero].god       = (SLONG) ((SBYTE) IOBuffer[offset++] );
  4516.             hero[whichhero].rune      = (SLONG) ((SBYTE) IOBuffer[offset++] );
  4517.             hero[whichhero].where     = (SLONG) ((SBYTE) IOBuffer[offset++] );
  4518.             hero[whichhero].homewhere = (SLONG) ((SBYTE) IOBuffer[offset++] );
  4519.             hero[whichhero].promoted  = (SLONG) ((SBYTE) IOBuffer[offset++] );
  4520.             hero[whichhero].wounded   = (FLAG)  ((SBYTE) IOBuffer[offset++] );
  4521.             hero[whichhero].wealth    = (SLONG) ((IOBuffer[offset++] * 256) + IOBuffer[offset++]);
  4522.             hero[whichhero].glory     = (SLONG) ((IOBuffer[offset++] * 256) + IOBuffer[offset++]);
  4523.             hero[whichhero].luck      = (SLONG) ((IOBuffer[offset++] * 256) + IOBuffer[offset++]);
  4524.             hero[whichhero].sea       = (SLONG) ((SBYTE) IOBuffer[offset++]);
  4525.             hero[whichhero].loseturn  = (FLAG)  ((SBYTE) IOBuffer[offset++]);
  4526.             hero[whichhero].maidens   = (SLONG) ((SBYTE) IOBuffer[offset++]);
  4527.         }
  4528.         for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
  4529.         {   jarl[whichjarl].where     = (SLONG) ((SBYTE) IOBuffer[offset++]);
  4530.             jarl[whichjarl].homewhere = (SLONG) ((SBYTE) IOBuffer[offset++]);
  4531.             jarl[whichjarl].face      = (SLONG) ((SBYTE) IOBuffer[offset++]);
  4532.             jarl[whichjarl].hero      = (SLONG) ((SBYTE) IOBuffer[offset++]);
  4533.             jarl[whichjarl].taken     = (FLAG)  ((SBYTE) IOBuffer[offset++]);
  4534.             jarl[whichjarl].sea       = (SLONG) ((SBYTE) IOBuffer[offset++]);
  4535.             jarl[whichjarl].loseturn  = (FLAG)  ((SBYTE) IOBuffer[offset++]);
  4536.             jarl[whichjarl].alive     = (FLAG)  ((SBYTE) IOBuffer[offset++]);
  4537.         }
  4538.         for (whichmonster = 0; whichmonster <= MONSTERS; whichmonster++)
  4539.         {   monster[whichmonster].taken    = (FLAG)  ((SBYTE) IOBuffer[offset++]);
  4540.             monster[whichmonster].alive    = (FLAG)  ((SBYTE) IOBuffer[offset++]);
  4541.             monster[whichmonster].where    = (SLONG) ((SBYTE) IOBuffer[offset++]);
  4542.             monster[whichmonster].wealth   = (SLONG) ((SBYTE) IOBuffer[offset++]);
  4543.             monster[whichmonster].sea      = (SLONG) ((SBYTE) IOBuffer[offset++]);
  4544.             offset++; // skip monster[].loseturn
  4545.         }
  4546.         for (whichtreasure = 0; whichtreasure <= TREASURES; whichtreasure++)
  4547.         {   treasure[whichtreasure].taken         = (FLAG)  ((SBYTE) IOBuffer[offset++]);
  4548.             treasure[whichtreasure].possessor     = (FLAG)  ((SBYTE) IOBuffer[offset++]);
  4549.             treasure[whichtreasure].possessortype = (SLONG) ((SBYTE) IOBuffer[offset++]);
  4550.             treasure[whichtreasure].where         = (SLONG) ((SBYTE) IOBuffer[offset++]);
  4551.         }
  4552.         for (whichsord = 0; whichsord <= SORDS; whichsord++)
  4553.         {   sord[whichsord].taken         = (FLAG)  ((SBYTE) IOBuffer[offset++]);
  4554.             sord[whichsord].possessor     = (FLAG)  ((SBYTE) IOBuffer[offset++]);
  4555.             sord[whichsord].possessortype = (SLONG) ((SBYTE) IOBuffer[offset++]);
  4556.             sord[whichsord].where         = (SLONG) ((SBYTE) IOBuffer[offset++]);
  4557.         }
  4558.         for (whichcountry = 0; whichcountry <= 35; whichcountry++)
  4559.         {   world[whichcountry].hero = (SLONG) ((SBYTE) IOBuffer[offset++]);
  4560.             world[whichcountry].is   = (FLAG)  ((SBYTE) IOBuffer[offset++]);
  4561.         }
  4562.         // no need to read version string
  4563.         Close(FileHandle);
  4564.         // FileHandle = NULL;
  4565.  
  4566.         strcpy(pathname, newpathname);
  4567.  
  4568.         for (whichhero = 0; whichhero <= HEROES; whichhero++)
  4569.         {   GT_SetGadgetAttrs(CycleGadgetPtr[whichhero], MainWindowPtr, NULL, GA_Disabled, TRUE, TAG_DONE);
  4570.         }
  4571.         GT_SetGadgetAttrs(SpeedGadgetPtr, MainWindowPtr, NULL, GA_Disabled, TRUE, TAG_DONE);
  4572.  
  4573.         for (whichcountry = 0; whichcountry <= 65; whichcountry++)
  4574.         {   for (whichslot = 0; whichslot <= SLOTS; whichslot++)
  4575.             {   world[whichcountry].slot[whichslot] = FALSE;
  4576.         }   }
  4577.  
  4578.         for (whichhero = 0; whichhero <= HEROES; whichhero++)
  4579.         {   if (hero[whichhero].promoted == -1)
  4580.             {   hero[whichhero].name     = trueheroname[whichhero];
  4581.                 hero[whichhero].strength = HERO_STRENGTH;
  4582.                 hero[whichhero].moves    = HERO_MOVES;
  4583.             } else
  4584.             {   hero[whichhero].name     = jarl[hero[whichhero].promoted].name;
  4585.                 hero[whichhero].strength = jarl[hero[whichhero].promoted].strength;
  4586.                 hero[whichhero].moves    = jarl[hero[whichhero].promoted].moves;
  4587.             }
  4588.             deselect_hero(whichhero, FALSE);
  4589.             if (hero[whichhero].alive)
  4590.             {   move_hero(whichhero, FALSE);
  4591.             } else
  4592.             {   remove_hero(whichhero, FALSE);
  4593.         }   }
  4594.  
  4595.         for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
  4596.         {   jarl[whichjarl].recruitable = FALSE;
  4597.             if (jarl[whichjarl].alive)
  4598.             {   if (jarl[whichjarl].face == FACEUP)
  4599.                 {   revealjarl(whichjarl, FALSE);
  4600.                 } else
  4601.                 {   // assert(jarl[whichjarl].face == FACEDOWN);
  4602.                     hidejarl(whichjarl, FALSE);
  4603.                 }
  4604.                 move_jarl(whichjarl, FALSE);
  4605.             } else
  4606.             {   remove_jarl(whichjarl, FALSE);
  4607.         }   }
  4608.  
  4609.         for (whichmonster = 0; whichmonster <= MONSTERS; whichmonster++)
  4610.         {   if (monster[whichmonster].alive)
  4611.             {   move_monster(whichmonster, FALSE);
  4612.             } else
  4613.             {   remove_monster(whichmonster, FALSE);
  4614.         }   }
  4615.  
  4616.         darken();
  4617.         drawmap();
  4618.         refreshcounters();
  4619.  
  4620.         if (faxirides == -1)
  4621.         {   faxirides = 0;
  4622.             faxi_disappear();
  4623.         }
  4624.  
  4625.         strcpy(saystring, GetCatalogStr(li.li_Catalog, MSG_LOADED, "Loaded"));
  4626.         strcat(saystring, " ");
  4627.         strcat(saystring, pathname);
  4628.         strcat(saystring, ".");
  4629.         say(LOWER);
  4630.         return(TRUE);
  4631. }   }
  4632.  
  4633. MODULE void savegame(FLAG saveas)
  4634. {   SLONG offset = 12, whichhero, whichjarl, whichmonster, whichcountry,
  4635.           whichtreasure, whichsord;
  4636.     FLAG  cont = TRUE;
  4637.     TEXT  newpathname[255];
  4638.     BPTR  FileHandle /* = NULL */ ;
  4639.  
  4640.     strcpy(newpathname, pathname);
  4641.     if (saveas || newpathname[0] == 0)
  4642.     {   if
  4643.         (   AslRequestTags
  4644.             (   ASLRqPtr,
  4645.                 ASL_Hail, GetCatalogStr(li.li_Catalog, MSG_SAVE_GAME, "Save Game"),
  4646.                 ASL_FuncFlags, FILF_PATGAD | FILF_SAVE,
  4647.                 TAG_DONE
  4648.             )
  4649.          && *(ASLRqPtr->rf_File) != 0
  4650.         )
  4651.         {   strcpy(newpathname, ASLRqPtr->rf_Dir);
  4652.             AddPart(newpathname, ASLRqPtr->rf_File, 254);
  4653.         } else
  4654.         {   cont = FALSE;
  4655.     }   }
  4656.     if (!cont)
  4657.     {   return;
  4658.     }
  4659.  
  4660.     strcpy(saystring, GetCatalogStr(li.li_Catalog, MSG_SAVING, "Saving"));
  4661.     strcat(saystring, " ");
  4662.     strcat(saystring, newpathname);
  4663.     strcat(saystring, "...");
  4664.     say(LOWER);
  4665.  
  4666.     if (!(FileHandle = Open(newpathname, MODE_NEWFILE)))
  4667.     {   strcpy(saystring, GetCatalogStr(li.li_Catalog, MSG_CANT_OPEN, "Can't open"));
  4668.         strcat(saystring, " ");
  4669.         strcat(saystring, newpathname);
  4670.         strcat(saystring, " ");
  4671.         strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_FOR_WRITING, "for writing"));
  4672.         strcat(saystring, "!");
  4673.         say(LOWER);
  4674.         anykey();
  4675.         return;
  4676.     }
  4677.  
  4678.     /* write header
  4679.        SAGA 1.0 *#%
  4680.        012345678901
  4681.        where * is NULL byte and # is turn and % is faxi rides */
  4682.  
  4683.     strcpy(IOBuffer, "SAGA 1.0 ");
  4684.     IOBuffer[10] = (SBYTE) turn;
  4685.     IOBuffer[11] = (SBYTE) faxirides;
  4686.  
  4687.     for (whichhero = 0; whichhero <= HEROES; whichhero++)
  4688.     {    IOBuffer[offset++] = (SBYTE) hero[whichhero].control;
  4689.          IOBuffer[offset++] = (SBYTE) hero[whichhero].alive;
  4690.          IOBuffer[offset++] = (SBYTE) hero[whichhero].verydead;
  4691.          IOBuffer[offset++] = (SBYTE) hero[whichhero].moves;
  4692.          IOBuffer[offset++] = (SBYTE) hero[whichhero].god;
  4693.          IOBuffer[offset++] = (SBYTE) hero[whichhero].rune;
  4694.          IOBuffer[offset++] = (SBYTE) hero[whichhero].where;
  4695.          IOBuffer[offset++] = (SBYTE) hero[whichhero].homewhere;
  4696.          IOBuffer[offset++] = (SBYTE) hero[whichhero].promoted;
  4697.          IOBuffer[offset++] = (SBYTE) hero[whichhero].wounded;
  4698.          IOBuffer[offset++] = (UBYTE) (hero[whichhero].wealth / 256);
  4699.          IOBuffer[offset++] = (UBYTE) (hero[whichhero].wealth % 256);
  4700.          IOBuffer[offset++] = (UBYTE) (hero[whichhero].glory  / 256);
  4701.          IOBuffer[offset++] = (UBYTE) (hero[whichhero].glory  % 256);
  4702.          IOBuffer[offset++] = (UBYTE) (hero[whichhero].luck   / 256);
  4703.          IOBuffer[offset++] = (UBYTE) (hero[whichhero].luck   % 256);
  4704.          IOBuffer[offset++] = (SBYTE) hero[whichhero].sea;
  4705.          IOBuffer[offset++] = (SBYTE) hero[whichhero].loseturn;
  4706.          IOBuffer[offset++] = (SBYTE) hero[whichhero].maidens;
  4707.     }
  4708.     for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
  4709.     {    IOBuffer[offset++] = (SBYTE) jarl[whichjarl].where;
  4710.          IOBuffer[offset++] = (SBYTE) jarl[whichjarl].homewhere;
  4711.          IOBuffer[offset++] = (SBYTE) jarl[whichjarl].face;
  4712.          IOBuffer[offset++] = (SBYTE) jarl[whichjarl].hero;
  4713.          IOBuffer[offset++] = (SBYTE) jarl[whichjarl].taken;
  4714.          IOBuffer[offset++] = (SBYTE) jarl[whichjarl].sea;
  4715.          IOBuffer[offset++] = (SBYTE) jarl[whichjarl].loseturn;
  4716.          IOBuffer[offset++] = (SBYTE) jarl[whichjarl].alive;
  4717.     }
  4718.     for (whichmonster = 0; whichmonster <= MONSTERS; whichmonster++)
  4719.     {    IOBuffer[offset++] = (SBYTE) monster[whichmonster].taken;
  4720.          IOBuffer[offset++] = (SBYTE) monster[whichmonster].alive;
  4721.          IOBuffer[offset++] = (SBYTE) monster[whichmonster].where;
  4722.          IOBuffer[offset++] = (SBYTE) monster[whichmonster].wealth;
  4723.          IOBuffer[offset++] = (SBYTE) monster[whichmonster].sea;
  4724.          IOBuffer[offset++] = (SBYTE) 0; // skip monster loseturn
  4725.     }
  4726.     for (whichtreasure = 0; whichtreasure <= TREASURES; whichtreasure++)
  4727.     {    IOBuffer[offset++] = (SBYTE) treasure[whichtreasure].taken;
  4728.          IOBuffer[offset++] = (SBYTE) treasure[whichtreasure].possessor;
  4729.          IOBuffer[offset++] = (SBYTE) treasure[whichtreasure].possessortype;
  4730.          IOBuffer[offset++] = (SBYTE) treasure[whichtreasure].where;
  4731.     }
  4732.     for (whichsord = 0; whichsord <= SORDS; whichsord++)
  4733.     {    IOBuffer[offset++] = (SBYTE) sord[whichsord].taken;
  4734.          IOBuffer[offset++] = (SBYTE) sord[whichsord].possessor;
  4735.          IOBuffer[offset++] = (SBYTE) sord[whichsord].possessortype;
  4736.          IOBuffer[offset++] = (SBYTE) sord[whichsord].where;
  4737.     }
  4738.     for (whichcountry = 0; whichcountry <= 35; whichcountry++)
  4739.     {   IOBuffer[offset++] = (SBYTE) world[whichcountry].hero;
  4740.         IOBuffer[offset++] = (SBYTE) world[whichcountry].is;
  4741.     }
  4742.  
  4743.     if (Write(FileHandle, IOBuffer, offset) != offset)
  4744.     {   Close(FileHandle);
  4745.         // FileHandle = NULL;
  4746.         strcpy(saystring, GetCatalogStr(li.li_Catalog, MSG_CANT_WRITE_TO, "Can't write to"));
  4747.         strcat(saystring, " ");
  4748.         strcat(saystring, newpathname);
  4749.         strcat(saystring, "!");
  4750.         say(LOWER);
  4751.         anykey();
  4752.         return;
  4753.     }
  4754.  
  4755.     /* write version string */
  4756.     Write(FileHandle, VERSION, strlen(VERSION));
  4757.  
  4758.     Close(FileHandle);
  4759.     // FileHandle = NULL;
  4760.  
  4761.     strcpy(pathname, newpathname);
  4762.  
  4763.     strcpy(saystring, GetCatalogStr(li.li_Catalog, MSG_SAVED, "Saved"));
  4764.     strcat(saystring, " ");
  4765.     strcat(saystring, pathname);
  4766.     strcat(saystring, ".");
  4767.     say(LOWER);
  4768.     // no need for anykey(), as there is one when we return anyway.
  4769. }
  4770.  
  4771. MODULE SLONG odin_tyr(SLONG whichhero, FLAG attacking)
  4772. {   SLONG whichjarl, whichprayer;
  4773.     SLONG adjustment = 0;
  4774.  
  4775.     if (hero[whichhero].god == ODIN)
  4776.     {   hero[whichhero].god = -1;
  4777.         whichprayer = d6();
  4778.         strcpy(saystring, "Odin");
  4779.  
  4780.         if (whichprayer == 1)
  4781.         {   adjustment = -3;
  4782.  
  4783.             strcat(saystring, " ");
  4784.             strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_AIDS_HERO, "aids hero"));
  4785.             strcat(saystring, " ");
  4786.             strcat(saystring, hero[whichhero].name);
  4787.             strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_S_E_B_A_3_T_T_S, "'s enemy by adding 3 to their strength"));
  4788.             strcat(saystring, ".");
  4789.         } elif (whichprayer == 2)
  4790.         {   adjustment = -1;
  4791.  
  4792.             strcat(saystring, " ");
  4793.             strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_SENDS_A_WOLF_TO_AID_HERO, "sends a wolf to aid hero"));
  4794.             strcat(saystring, " ");
  4795.             strcat(saystring, hero[whichhero].name);
  4796.             strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_S_ENEMY, "'s enemy"));
  4797.             strcat(saystring, ".");
  4798.         } elif (whichprayer == 3)
  4799.         {   strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_S_R_A_S_B_H_T_O_T_B, "'s ravens are sent by him to observe the battle"));
  4800.             strcat(saystring, ".");
  4801.         } elif (whichprayer == 4)
  4802.         {   adjustment = 1;
  4803.  
  4804.             strcat(saystring, " ");
  4805.             strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_SENDS_A_WOLF_TO_AID_HERO, "sends a wolf to aid hero"));
  4806.             strcat(saystring, " ");
  4807.             strcat(saystring, hero[whichhero].name);
  4808.             strcat(saystring, ".");
  4809.         } elif (whichprayer == 5)
  4810.         {   adjustment = 3;
  4811.  
  4812.             strcat(saystring, " ");
  4813.             strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_AIDS_HERO, "aids hero"));
  4814.             strcat(saystring, " ");
  4815.             strcat(saystring, hero[whichhero].name);
  4816.             strcat(saystring, " ");
  4817.             strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_BY_ADDING_3_TO_HIS_STRENGTH, "by adding 3 to his strength"));
  4818.             strcat(saystring, ".");
  4819.         } else
  4820.         {   // assert(whichprayer == 6);
  4821.  
  4822.             adjustment = 5;
  4823.             hero[whichhero].glory += 3;
  4824.  
  4825.             strcat(saystring, " ");
  4826.             strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_INTERVENES_PERSONALLY, "intervenes personally"));
  4827.             strcat(saystring, ".");
  4828.         }
  4829.         say(LOWER);
  4830.         anykey();
  4831.     } elif (hero[whichhero].god == TYR)
  4832.     {   hero[whichhero].god = -1;
  4833.         whichprayer = d6();
  4834.         strcpy(saystring, "Tyr ");
  4835.  
  4836.         if (whichprayer == 1)
  4837.         {   adjustment = -1;
  4838.  
  4839.             strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_AIDS_HERO, "aids hero"));
  4840.             strcat(saystring, " ");
  4841.             strcat(saystring, hero[whichhero].name);
  4842.             strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_S_E_B_A_1_T_T_S, "'s enemy by adding 1 to their strength"));
  4843.             strcat(saystring, ".");
  4844.         } elif (whichprayer == 2 || whichprayer == 3)
  4845.         {   strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_D_T_T_F_I_B_F, "decides that the fight is balanced fairly"));
  4846.             strcat(saystring, ".");
  4847.         } elif (whichprayer == 4)
  4848.         {   adjustment = 1;
  4849.  
  4850.             strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_AIDS_HERO, "aids hero"));
  4851.             strcat(saystring, " ");
  4852.             strcat(saystring, hero[whichhero].name);
  4853.             strcat(saystring, " ");
  4854.             strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_BY_ADDING_1_TO_HIS_STRENGTH, "by adding 1 to his strength"));
  4855.             strcat(saystring, ".");
  4856.         } elif (whichprayer == 5)
  4857.         {   adjustment = 2;
  4858.  
  4859.             strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_AIDS_HERO, "aids hero"));
  4860.             strcat(saystring, " ");
  4861.             strcat(saystring, hero[whichhero].name);
  4862.             strcat(saystring, " ");
  4863.             strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_BY_ADDING_2_TO_HIS_STRENGTH, "by adding 2 to his strength"));
  4864.             strcat(saystring, ".");
  4865.         } else
  4866.         {   assert(whichprayer == 6);
  4867.  
  4868.             adjustment = 1; // for the hero himself
  4869.             if (attacking)
  4870.             {   for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
  4871.                 {   if (jarl[whichjarl].attacking)
  4872.                     {   adjustment++;
  4873.             }   }   }
  4874.             else
  4875.             {   for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
  4876.                 {   if (jarl[whichjarl].defending)
  4877.                     {   adjustment++;
  4878.             }   }   }
  4879.  
  4880.             strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_AIDS_HERO, "aids hero"));
  4881.             strcat(saystring, " ");
  4882.             strcat(saystring, hero[whichhero].name);
  4883.             strcat(saystring, " ");
  4884.             strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_B_A_1_T_T_S_O_E_P_O_H_S, "by adding 1 to the strength of each person on his side"));
  4885.             strcat(saystring, ".");
  4886.         }
  4887.         say(LOWER);
  4888.         anykey();
  4889.     }
  4890.     return(adjustment);
  4891. }
  4892.  
  4893. MODULE void pray(SLONG whichhero)
  4894. {   SLONG decision;
  4895.  
  4896.     decision = d6();
  4897.     if (decision == 1 || (hero[whichhero].rune == AMSIR && decision == 2))
  4898.     {   gods(whichhero);
  4899. }   }
  4900.  
  4901. MODULE void amiga_rout(SLONG routedtype, SLONG routed)
  4902. {   SLONG decision, whichmove, moves;
  4903.     FLAG freemove;
  4904.  
  4905.     if (routedtype == HERO)
  4906.     {   hero[routed].routed = TRUE;
  4907.     } elif (routedtype == JARL)
  4908.     {   jarl[routed].routed = TRUE;
  4909.     }
  4910.  
  4911.     moves = getmoves(routedtype, routed, FALSE);
  4912.     if (moves < 1)
  4913.     {   return;
  4914.     }
  4915.  
  4916.     if (routedtype == HERO || routedtype == JARL)
  4917.     {   saywho(routedtype, routed, FALSE, FALSE);
  4918.     } else
  4919.     {   // assert(routedtype == MONSTER);
  4920.         strcpy(saystring, monstertypes[monster[routed].species]);
  4921.         strcat(saystring, " ");
  4922.         strcat(saystring, monster[routed].name);
  4923.         strcat(saystring, " ");
  4924.     }
  4925.  
  4926.     strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_IS_BEING_ROUTED, "is being routed"));
  4927.     strcat(saystring, "...");
  4928.     say(LOWER);
  4929.  
  4930.     if (routedtype == HERO)
  4931.     {   freemove = FALSE;
  4932.         select_hero(routed);
  4933.         for (whichmove = 1; whichmove <= moves; whichmove++)
  4934.         {   do
  4935.             {   decision = rand() % (CONNECTIONS + 1);
  4936.             } while (world[hero[routed].where].connection[decision] == -1);
  4937.             if
  4938.             (   hero[routed].sea == BAD
  4939.              && (   world[world[hero[routed].where].connection[decision]].type == SEA
  4940.                  || world[world[hero[routed].where].connection[decision]].type == ISLE
  4941.             )   )
  4942.             {   whichmove--;
  4943.             } else
  4944.             {   unslot_hero(routed);
  4945.                 hero[routed].where = world[hero[routed].where].connection[decision];
  4946.                 move_hero(routed, TRUE);
  4947.                 if (hero[routed].sea == GOOD)
  4948.                 {   if (!freemove)
  4949.                     {   if
  4950.                         (   world[hero[routed].where].type == SEA
  4951.                          || world[hero[routed].where].type == ISLE
  4952.                         )
  4953.                         {   freemove = TRUE;
  4954.                     }   }
  4955.                     else
  4956.                     {   if
  4957.                         (   world[hero[routed].where].type == LAND
  4958.                         )
  4959.                         {   freemove = FALSE;
  4960.                         } else
  4961.                         {   whichmove--;
  4962.         }   }   }   }   }
  4963.         deselect_hero(routed, TRUE);
  4964.     } elif (routedtype == JARL)
  4965.     {   select_jarl(routed);
  4966.         for (whichmove = 1; whichmove <= moves; whichmove++)
  4967.         {   do
  4968.             {   decision = rand() % (CONNECTIONS + 1);
  4969.             } while (world[jarl[routed].where].connection[decision] == -1);
  4970.             if
  4971.             (   jarl[routed].sea == BAD
  4972.              && (   world[world[jarl[routed].where].connection[decision]].type == SEA
  4973.                  || world[world[jarl[routed].where].connection[decision]].type == ISLE
  4974.             )   )
  4975.             {   whichmove--;
  4976.             } else
  4977.             {   unslot_jarl(routed);
  4978.                 jarl[routed].where = world[jarl[routed].where].connection[decision];
  4979.                 move_jarl(routed, TRUE);
  4980.         }   }
  4981.         deselect_jarl(routed);
  4982.     } elif (routedtype == MONSTER)
  4983.     {   // select_monster(routed);
  4984.         for (whichmove = 1; whichmove <= moves; whichmove++)
  4985.         {   do
  4986.             {   decision = rand() % (CONNECTIONS + 1);
  4987.             } while (world[monster[routed].where].connection[decision] == -1);
  4988.             if
  4989.             (   monster[routed].sea == BAD
  4990.              && (   world[world[monster[routed].where].connection[decision]].type == SEA
  4991.                  || world[world[monster[routed].where].connection[decision]].type == ISLE
  4992.             )   )
  4993.             {   whichmove--;
  4994.             } else
  4995.             {   unslot_monster(routed);
  4996.                 monster[routed].where = world[monster[routed].where].connection[decision];
  4997.                 move_monster(routed, TRUE);
  4998.         }   }
  4999.         // deselect_monster(routed);
  5000. }   }
  5001.  
  5002. MODULE void human_rout(SLONG routedtype, SLONG routed, SLONG routerhero)
  5003. {   SLONG country,
  5004.           oldcountry = -1,
  5005.           moves,
  5006.           whichconnection,
  5007.           whichmove;
  5008.     FLAG  legal, freemove;
  5009.  
  5010.     moves = getmoves(routedtype, routed, FALSE);
  5011.  
  5012.     if (moves == 0)
  5013.     {   return;
  5014.     }
  5015.  
  5016.     if (routedtype == HERO)
  5017.     {   select_hero(routed);
  5018.         oldcountry = hero[routed].where;
  5019.     } elif (routedtype == JARL)
  5020.     {   select_jarl(routed);
  5021.         oldcountry = jarl[routed].where;
  5022.     } elif (routedtype == MONSTER)
  5023.     {   // select_monster(routed);
  5024.         oldcountry = monster[routed].where;
  5025.     }
  5026.  
  5027.     whichmove = 1;
  5028.     freemove = FALSE;
  5029.     do
  5030.     {   saywho(HERO, routerhero, TRUE, FALSE);
  5031.         strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_ROUT, "rout"));
  5032.         strcat(saystring, " ");
  5033.         stcl_d(numberstring, whichmove);
  5034.         strcat(saystring, numberstring);
  5035.         strcat(saystring, " ");
  5036.         strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_OF, "of"));
  5037.         strcat(saystring, " ");
  5038.         stcl_d(numberstring, moves);
  5039.         strcat(saystring, numberstring);
  5040.         strcat(saystring, " ");
  5041.         strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_FOR, "for"));
  5042.  
  5043.         if (routedtype == HERO || routedtype == JARL)
  5044.         {   saywho(routedtype, routed, FALSE, TRUE);
  5045.         } else
  5046.         {   // assert(routedtype == MONSTER);
  5047.             strcat(saystring, " ");
  5048.             strcat(saystring, monstertypes[monster[routed].species]);
  5049.             strcat(saystring, " ");
  5050.             strcat(saystring, monster[routed].name);
  5051.         }
  5052.         strcat(saystring, "?");
  5053.         say(LOWER);
  5054.  
  5055.         do
  5056.         {   country = getevent(COUNTRY, NULL);
  5057.         } while ((country < -3 || country > 65) || country == -1);
  5058.         if (country == -3)
  5059.         {   break;
  5060.         } elif (country == -2)
  5061.         {   whichmove = 1;
  5062.             if (routedtype == HERO)
  5063.             {   unslot_hero(routed);
  5064.                 hero[routed].where = oldcountry;
  5065.                 move_hero(routed, TRUE);
  5066.                 freemove = FALSE;
  5067.             } elif (routedtype == JARL)
  5068.             {   unslot_jarl(routed);
  5069.                 jarl[routed].where = oldcountry;
  5070.                 move_jarl(routed, TRUE);
  5071.             } else
  5072.             {   // assert(routedtype == MONSTER);
  5073.                 unslot_monster(routed);
  5074.                 monster[routed].where = oldcountry;
  5075.                 move_monster(routed, TRUE);
  5076.         }   }
  5077.         else
  5078.         {   legal = FALSE;
  5079.             for (whichconnection = 0; whichconnection <= CONNECTIONS; whichconnection++)
  5080.             {   if
  5081.                 (   (routedtype == HERO    && world[hero[routed].where].connection[whichconnection] == country)
  5082.                  || (routedtype == JARL    && world[jarl[routed].where].connection[whichconnection] == country)
  5083.                  || (routedtype == MONSTER && world[monster[routed].where].connection[whichconnection] == country)
  5084.                 )
  5085.                 {   legal = TRUE;
  5086.                     break; // for speed
  5087.             }   }
  5088.             if (legal)
  5089.             {   if (routedtype == HERO)
  5090.                 {   if
  5091.                     (   hero[routed].sea == BAD
  5092.                      && (   world[country].type == SEA
  5093.                          || world[country].type == ISLE
  5094.                     )   )
  5095.                     {   legal = FALSE;
  5096.                         saywho(HERO, routed, FALSE, FALSE);
  5097.                         strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_M_N_T_B_S_T_T, "may not travel by sea this turn"));
  5098.                         strcat(saystring, ".");
  5099.                         say(LOWER);
  5100.                         anykey();
  5101.                 }   }
  5102.                 elif (routedtype == JARL)
  5103.                 {   if
  5104.                     (   jarl[routed].sea == BAD
  5105.                      && (   world[country].type == SEA
  5106.                          || world[country].type == ISLE
  5107.                     )   )
  5108.                     {   legal = FALSE;
  5109.                         saywho(JARL, routed, FALSE, FALSE);
  5110.                         strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_M_N_T_B_S_T_T, "may not travel by sea this turn"));
  5111.                         strcat(saystring, ".");
  5112.                         say(LOWER);
  5113.                         anykey();
  5114.                 }   }
  5115.                 elif (routedtype == MONSTER)
  5116.                 {   if
  5117.                     (   monster[routed].sea == BAD
  5118.                      && (   world[country].type == SEA
  5119.                          || world[country].type == ISLE
  5120.                     )   )
  5121.                     {   legal = FALSE;
  5122.                         strcat(saystring, monstertypes[monster[routed].species]);
  5123.                         strcat(saystring, " ");
  5124.                         strcat(saystring, monster[routed].name);
  5125.                         strcat(saystring, " ");
  5126.                         strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_M_N_T_B_S_T_T, "may not travel by sea this turn"));
  5127.                         strcat(saystring, ".");
  5128.                         say(LOWER);
  5129.                         anykey();
  5130.             }   }   }
  5131.             if (legal)
  5132.             {   if (routedtype == HERO)
  5133.                 {   unslot_hero(routed);
  5134.                     hero[routed].where = country;
  5135.                     move_hero(routed, TRUE);
  5136.  
  5137.                     if (hero[routed].sea == GOOD)
  5138.                     {   if (!freemove)
  5139.                         {   if
  5140.                             (   world[hero[routed].where].type == SEA
  5141.                              || world[hero[routed].where].type == ISLE
  5142.                             )
  5143.                             {   freemove = TRUE;
  5144.                             }
  5145.                             whichmove++;
  5146.                         } else
  5147.                         {   if
  5148.                             (   world[hero[routed].where].type == LAND
  5149.                             )
  5150.                             {   freemove = FALSE;
  5151.                                 whichmove++;
  5152.                 }   }   }   }
  5153.                 elif (routedtype == JARL)
  5154.                 {   unslot_jarl(routed);
  5155.                     jarl[routed].where = country;
  5156.                     move_jarl(routed, TRUE);
  5157.                 } else
  5158.                 {   // assert(routedtype == MONSTER);
  5159.                     unslot_monster(routed);
  5160.                     monster[routed].where = country;
  5161.                     move_monster(routed, TRUE);
  5162.                 }
  5163.                 whichmove++;
  5164.             } else
  5165.             {   ; // DisplayBeep(ScreenPtr);
  5166.         }   }
  5167.     } while (whichmove <= moves);
  5168.  
  5169.     if (routedtype == HERO)
  5170.     {   deselect_hero(routed, TRUE);
  5171.     } elif (routedtype == JARL)
  5172.     {   deselect_jarl(routed);
  5173. }   }
  5174.  
  5175. MODULE SLONG getmoves(SLONG countertype, SLONG whichcounter, FLAG freyfaxi)
  5176. {   SLONG moves;
  5177.  
  5178.     if (countertype == HERO)
  5179.     {   moves = hero[whichcounter].moves;
  5180.     } elif (countertype == MONSTER)
  5181.     {   // assert(!freyfaxi);
  5182.         moves = monster[whichcounter].moves;
  5183.     } else
  5184.     {   assert(countertype == JARL);
  5185.         moves = jarl[whichcounter].moves;
  5186.     }
  5187.  
  5188.     if (freyfaxi)
  5189.     {   moves *= 2;
  5190.     }
  5191.  
  5192.     if
  5193.     (   countertype != MONSTER // so dragon's don't use magic treasures
  5194.      && treasure[MAGICSHIRT].possessortype == countertype
  5195.      && treasure[MAGICSHIRT].possessor     == whichcounter
  5196.     )
  5197.     {   // assert(treasure[MAGICSHIRT].where == -1);
  5198.         moves++;
  5199.     }
  5200.  
  5201.     if (countertype == HERO && hero[whichcounter].rune == EON)
  5202.     {   moves++;
  5203.     }
  5204.  
  5205.     if
  5206.     (   (countertype == HERO    && hero[whichcounter].loseturn)
  5207.      || (countertype == JARL    && jarl[whichcounter].loseturn)
  5208.      ||  countertype == MONSTER
  5209.     )
  5210.     {   moves = 0;
  5211.     }
  5212.  
  5213.     /* If you are stuck at sea or on an island, and can't travel
  5214.        by sea, then you can't move at all that turn. */
  5215.     if
  5216.     (   countertype == HERO
  5217.      && hero[whichcounter].sea == BAD
  5218.      && (   world[hero[whichcounter].where].type == SEA
  5219.          || world[hero[whichcounter].where].type == ISLE
  5220.     )   )
  5221.     {   moves = 0;
  5222.     } elif
  5223.     (   countertype == JARL
  5224.      && jarl[whichcounter].sea == BAD
  5225.      && (   world[jarl[whichcounter].where].type == SEA
  5226.          || world[jarl[whichcounter].where].type == ISLE
  5227.     )   )
  5228.     {   moves = 0;
  5229.     } elif
  5230.     (   countertype == MONSTER
  5231.      && monster[whichcounter].sea == BAD
  5232.      && (   world[monster[whichcounter].where].type == SEA
  5233.          || world[monster[whichcounter].where].type == ISLE
  5234.     )   )
  5235.     {   moves = 0;
  5236.     }
  5237.  
  5238.     return(moves);
  5239. }
  5240.  
  5241. MODULE void faxi_disappear(void)
  5242. {   if (faxirides == 0) // faxi disappears
  5243.     {   treasure[FREYFAXI].possessortype = -1; // noone
  5244.         treasure[FREYFAXI].possessor     = -1; // noone
  5245.         treasure[FREYFAXI].where         = -1; // nowhere
  5246.         // frey faxi won't be on the board at the moment anyway
  5247.         faxirides = -1; // so it only disappears once
  5248. }   }
  5249.  
  5250. MODULE void thor(SLONG whichhero)
  5251. {   SLONG whichprayer;
  5252.  
  5253.     if (hero[whichhero].god == THOR)
  5254.     {   hero[whichhero].god = -1;
  5255.         whichprayer = d6();
  5256.         strcpy(saystring, "Thor ");
  5257.  
  5258.         if (whichprayer >= 1 && whichprayer <= 3)
  5259.         {   strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_DECIDES_THAT_HERO, "decides that hero"));
  5260.             strcat(saystring, " ");
  5261.             strcat(saystring, hero[whichhero].name);
  5262.             strcat(saystring, " ");
  5263.             strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_DESERVES_NO_REWARD, "deserves no reward"));
  5264.             strcat(saystring, ".");
  5265.         } elif (whichprayer == 4 || whichprayer == 5)
  5266.         {   hero[whichhero].glory++;
  5267.  
  5268.             strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_REWARDS_HERO, "rewards hero"));
  5269.             strcat(saystring, " ");
  5270.             strcat(saystring, hero[whichhero].name);
  5271.             strcat(saystring, " ");
  5272.             strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_B_S_T_H_G_1_G, "by speaking to him, granting 1 glory"));
  5273.             strcat(saystring, ".");
  5274.         } else
  5275.         {   // assert(whichprayer == 6);
  5276.  
  5277.             hero[whichhero].glory += 2;
  5278.  
  5279.             strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_HONOURS_HERO, "honours hero"));
  5280.             strcat(saystring, " ");
  5281.             strcat(saystring, hero[whichhero].name);
  5282.             strcat(saystring, " ");
  5283.             strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_B_E_W_H_G_2_G, "by eating with him, granting 2 glory"));
  5284.             strcat(saystring, ".");
  5285.         }
  5286.         say(LOWER);
  5287.         anykey();
  5288. }   }
  5289.  
  5290. MODULE void dospell(SLONG spell, SLONG caster)
  5291. {   SLONG whichhero, whichjarl, whichmonster;
  5292.  
  5293.     if (spell == HAGALL || spell == JARA || d6() <= 3) // if it's a spell which doesn't have a saving throw, or the saving throw is missed
  5294.     {   strcat(saystring, ".");
  5295.         say(LOWER);
  5296.         anykey();
  5297.  
  5298.         for (whichhero = 0; whichhero <= HEROES; whichhero++)
  5299.         {   if
  5300.             (   hero[whichhero].control != NONE
  5301.              && hero[whichhero].alive
  5302.              && hero[whichhero].where == monster[caster].where
  5303.             )
  5304.             {   if (hero[whichhero].rune == SYGIL && d6() <= 3)
  5305.                 {   strcpy(saystring, GetCatalogStr(li.li_Catalog, MSG_HERO, "Hero"));
  5306.                     strcat(saystring, " ");
  5307.                     strcat(saystring, hero[whichhero].name);
  5308.                     strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_S_RUNE_PROTECTS_HIM, "'s rune protects him"));
  5309.                     strcat(saystring, ".");
  5310.                     say(LOWER);
  5311.                     anykey();
  5312.                 } else
  5313.                 {   if (spell == HAGALL)
  5314.                     {   hero[whichhero].hagall = TRUE;
  5315.                         hero[whichhero].sea    = BAD;
  5316.                     } elif (spell == JARA)
  5317.                     {   hero[whichhero].loseturn = TRUE;
  5318.                     } elif (spell == NIED)
  5319.                     {   hero[whichhero].loseturn = TRUE;
  5320.                         hero[whichhero].attacking = FALSE;
  5321.                     } elif (spell == WYNN)
  5322.                     {   hero[whichhero].glory -= 2;
  5323.                         if (hero[whichhero].glory < 0)
  5324.                         {   hero[whichhero].glory = 0;
  5325.                         }
  5326.                         amiga_rout(HERO, whichhero);
  5327.                         hero[whichhero].attacking = FALSE;
  5328.                     } elif (spell == YR)
  5329.                     {   wound(MONSTER, caster, -1, HERO, whichhero, whichhero);
  5330.                         hero[whichhero].attacking = FALSE;
  5331.         }   }   }   }
  5332.         for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
  5333.         {   if
  5334.             (   jarl[whichjarl].alive
  5335.              && jarl[whichjarl].where == monster[caster].where
  5336.             )
  5337.             {   if (spell == HAGALL)
  5338.                 {   jarl[whichjarl].hagall = TRUE;
  5339.                     jarl[whichjarl].sea    = BAD;
  5340.                 } elif (spell == JARA)
  5341.                 {   jarl[whichjarl].loseturn = TRUE;
  5342.                 } elif (spell == NIED)
  5343.                 {   jarl[whichjarl].loseturn = TRUE;
  5344.                     jarl[whichjarl].attacking = FALSE;
  5345.                 } elif (spell == WYNN)
  5346.                 {   amiga_rout(JARL, whichjarl);
  5347.                     jarl[whichjarl].attacking = FALSE;
  5348.                 } elif (spell == YR)
  5349.                 {   if (jarl[whichjarl].face == FACEUP)
  5350.                     {   wound(MONSTER, caster, -1, JARL, whichjarl, jarl[whichjarl].hero);
  5351.                         jarl[whichjarl].attacking = FALSE;
  5352.         }   }   }   }
  5353.         
  5354.         if (spell == HAGALL)
  5355.         {   for (whichmonster = 0; whichmonster <= MONSTERS; whichmonster++)
  5356.             {   if
  5357.                 (   monster[whichmonster].alive
  5358.                  && monster[whichmonster].where == monster[caster].where
  5359.                 )
  5360.                 {   monster[whichmonster].hagall = TRUE;
  5361.                     monster[whichmonster].sea    = BAD;
  5362.     }   }   }   }
  5363.     else
  5364.     {   strcat(saystring, ", ");
  5365.         strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_BUT_IT_FIZZLES, "but it fizzles"));
  5366.         strcat(saystring, "!");
  5367.         say(LOWER);
  5368.         anykey();
  5369. }   }
  5370.  
  5371. MODULE void cast(SLONG caster, SLONG whichspell)
  5372. {   strcpy(saystring, monstertypes[monster[caster].species]);
  5373.     strcat(saystring, " ");
  5374.     strcat(saystring, monster[caster].name);
  5375.     strcat(saystring, " ");
  5376.     strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_CASTS, "casts"));
  5377.     strcat(saystring, " ");
  5378.  
  5379.     switch(whichspell)
  5380.     {
  5381.     case HAGALL:
  5382.         strcat(saystring, "Hagall (");
  5383.         strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_HAIL_SLOW, "hail/slow"));
  5384.         strcat(saystring, ")");
  5385.  
  5386.         dospell(HAGALL, caster);
  5387.     break;
  5388.     case IS:
  5389.         world[monster[caster].where].is = TRUE;
  5390.         darken();
  5391.  
  5392.         strcat(saystring, "Is (");
  5393.         strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_ICE, "ice"));
  5394.         strcat(saystring, ").");
  5395.         say(LOWER);
  5396.         anykey();
  5397.     break;
  5398.     case JARA:
  5399.         strcat(saystring, "Jara (");
  5400.         strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_LOSE_NEXT_TURN, "lose next turn"));
  5401.         strcat(saystring, ")");
  5402.  
  5403.         dospell(JARA, caster);
  5404.     break;
  5405.     case NIED:
  5406.         strcat(saystring, "Nied (");
  5407.         strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_N_R_A_L_N_T, "no result and lose next turn"));
  5408.         strcat(saystring, ")");
  5409.  
  5410.         dospell(NIED, caster);
  5411.     break;
  5412.     case WYNN:
  5413.         strcat(saystring, "Wynn (");
  5414.         strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_FLEEING, "fleeing"));
  5415.         strcat(saystring, ")");
  5416.  
  5417.         dospell(WYNN, caster);
  5418.     break;
  5419.     case YR:
  5420.         strcat(saystring, "Yr (");
  5421.         strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_WOUNDING, "wounding"));
  5422.         strcat(saystring, ")");
  5423.  
  5424.         dospell(YR, caster);
  5425.     break;
  5426.     default:
  5427.         // assert(0);
  5428.     break;
  5429. }   }
  5430.  
  5431. MODULE void darken(void)
  5432. {   SLONG whichcountry, colour;
  5433.  
  5434.     for (whichcountry = 0; whichcountry <= 35; whichcountry++)
  5435.     {   if (whichcountry >= 9 && whichcountry <= 11)
  5436.         {   colour = whichcountry + 80;
  5437.         } else
  5438.         {   colour = whichcountry + 8;
  5439.         }
  5440.         if (world[whichcountry].is)
  5441.         {   SetRGB4(&ScreenPtr->ViewPort, colour, 12, 12, 12); // light grey ice
  5442.         } elif (world[whichcountry].hero != -1)
  5443.         {   SetRGB4
  5444.             (   &ScreenPtr->ViewPort,
  5445.                 colour,
  5446.                 herocolour[world[whichcountry].hero].red,
  5447.                 herocolour[world[whichcountry].hero].green,
  5448.                 herocolour[world[whichcountry].hero].blue
  5449.             );
  5450.         } else
  5451.         {   SetRGB4
  5452.             (   &ScreenPtr->ViewPort,
  5453.                 colour,
  5454.                 taxcolours[world[whichcountry].tax].red,
  5455.                 taxcolours[world[whichcountry].tax].green,
  5456.                 taxcolours[world[whichcountry].tax].blue
  5457.             );
  5458. }   }   }
  5459.  
  5460. MODULE SLONG checkcountry(WORD mousex, WORD mousey)
  5461. {   SLONG country;
  5462.  
  5463.     country = ReadPixel(MainWindowPtr->RPort, mousex, mousey);
  5464.     if (country == 80 || country == 81 || country == 91)
  5465.     {   country = 11; // Scandia
  5466.     } elif (country == 82 || country == 83)
  5467.     {   country = 30; // Pictland
  5468.     } elif (country == 84 || country == 85)
  5469.     {   country = 31; // Hebrides
  5470.     } elif (country == 89)
  5471.     {   country =  9; // Suder Gotland
  5472.     } elif (country == 90)
  5473.     {   country = 10; // Juteland
  5474.     } else
  5475.     {   country -= 8;
  5476.     }
  5477.  
  5478.     return(country);
  5479. }
  5480.  
  5481. MODULE void infowindow(SLONG countertype, SLONG whichcounter)
  5482. {   SLONG                lines,
  5483.                          leftlines     = 0,
  5484.                          rightlines    = 0,
  5485.                          oldwhichline,
  5486.                          whichline,
  5487.                          whichcountry,
  5488.                          whichjarl,
  5489.                          whichhero,
  5490.                          whichtreasure,
  5491.                          whichsord,
  5492.                          wide,
  5493.                          whichmonster;
  5494.     FLAG                 counterrow = FALSE,
  5495.                          done       = FALSE,
  5496.                          ok;
  5497.     ULONG                class;
  5498.     UWORD                code, qual;
  5499.     struct IntuiMessage* MsgPtr;
  5500.  
  5501.     if (countertype == HERO)
  5502.     {   strcpy(line[LEFTSIDE][0], GetCatalogStr(li.li_Catalog, MSG_HERO_NAME, "Hero Name"));
  5503.         strcat(line[LEFTSIDE][0], ":");
  5504.         pad(line[LEFTSIDE][0]);
  5505.         strcat(line[LEFTSIDE][0], hero[whichcounter].name);
  5506.  
  5507.         strcpy(line[LEFTSIDE][1], GetCatalogStr(li.li_Catalog, MSG_CONTROL, "Control"));
  5508.         strcat(line[LEFTSIDE][1], ":");
  5509.         pad(line[LEFTSIDE][1]);
  5510.         if (hero[whichcounter].control == HUMAN)
  5511.         {   strcat(line[LEFTSIDE][1], GetCatalogStr(li.li_Catalog, MSG_HUMAN, "Human"));
  5512.         } else
  5513.         {   // assert(hero[whichcounter].control == AMIGA);
  5514.             strcat(line[LEFTSIDE][1], "Amiga");
  5515.         }
  5516.         
  5517.         strcpy(line[LEFTSIDE][2], GetCatalogStr(li.li_Catalog, MSG_COMBAT_STRENGTH, "Combat Strength"));
  5518.         strcat(line[LEFTSIDE][2], ":");
  5519.         pad(line[LEFTSIDE][2]);
  5520.         stcl_d(numberstring, hero[whichcounter].strength);
  5521.         strcat(line[LEFTSIDE][2], numberstring);
  5522.         
  5523.         strcpy(line[LEFTSIDE][3], GetCatalogStr(li.li_Catalog, MSG_MOVEMENT_FACTOR, "Movement Factor"));
  5524.         strcat(line[LEFTSIDE][3], ":");
  5525.         pad(line[LEFTSIDE][3]);
  5526.         stcl_d(numberstring, hero[whichcounter].moves);
  5527.         strcat(line[LEFTSIDE][3], numberstring);
  5528.         
  5529.         strcpy(line[LEFTSIDE][4], GetCatalogStr(li.li_Catalog, MSG_GLORY, "Glory"));
  5530.         strcat(line[LEFTSIDE][4], ":");
  5531.         pad(line[LEFTSIDE][4]);
  5532.         stcl_d(numberstring, hero[whichcounter].glory);
  5533.         strcat(line[LEFTSIDE][4], numberstring);
  5534.         
  5535.         strcpy(line[LEFTSIDE][5], GetCatalogStr(li.li_Catalog, MSG_LUCK, "Luck"));
  5536.         strcat(line[LEFTSIDE][5], ":");
  5537.         pad(line[LEFTSIDE][5]);
  5538.         stcl_d(numberstring, hero[whichcounter].luck);
  5539.         strcat(line[LEFTSIDE][5], numberstring);
  5540.         
  5541.         strcpy(line[LEFTSIDE][6], GetCatalogStr(li.li_Catalog, MSG_WEALTH, "Wealth"));
  5542.         strcat(line[LEFTSIDE][6], ":");
  5543.         pad(line[LEFTSIDE][6]);
  5544.         stcl_d(numberstring, hero[whichcounter].wealth);
  5545.         strcat(line[LEFTSIDE][6], numberstring);
  5546.  
  5547.         print_location(hero[whichcounter].where, 7);
  5548.  
  5549.         strcpy(line[LEFTSIDE][8], GetCatalogStr(li.li_Catalog, MSG_HOMELAND, "Homeland"));
  5550.         strcat(line[LEFTSIDE][8], ":");
  5551.         pad(line[LEFTSIDE][8]);
  5552.         strcat(line[LEFTSIDE][8], world[hero[whichcounter].homewhere].name);
  5553.         strcat(line[LEFTSIDE][8], " (");
  5554.         stcl_d(numberstring, world[hero[whichcounter].homewhere].tax);
  5555.         strcat(line[LEFTSIDE][8], numberstring);
  5556.         strcat(line[LEFTSIDE][8], ")");
  5557.         
  5558.         strcpy(line[LEFTSIDE][9], GetCatalogStr(li.li_Catalog, MSG_MAIDENS, "Maidens"));
  5559.         strcat(line[LEFTSIDE][9], ":");
  5560.         pad(line[LEFTSIDE][9]);
  5561.         stcl_d(numberstring, hero[whichcounter].maidens);
  5562.         strcat(line[LEFTSIDE][9], numberstring);
  5563.       
  5564.         strcpy(line[LEFTSIDE][10], GetCatalogStr(li.li_Catalog, MSG_RUNE, "Rune"));
  5565.         strcat(line[LEFTSIDE][10], ":");
  5566.         pad(line[LEFTSIDE][10]);
  5567.         if (hero[whichcounter].rune == -1)
  5568.         {   strcat(line[LEFTSIDE][10], GetCatalogStr(li.li_Catalog, MSG_NONE, "None"));
  5569.         } else
  5570.         {   strcat(line[LEFTSIDE][10], runename[hero[whichcounter].rune]);
  5571.         }
  5572.  
  5573.         strcpy(line[LEFTSIDE][11], GetCatalogStr(li.li_Catalog, MSG_SWORD, "Sword"));
  5574.         strcat(line[LEFTSIDE][11], ":");
  5575.         pad(line[LEFTSIDE][11]);
  5576.         ok = FALSE;
  5577.         for (whichsord = 0; whichsord <= SORDS; whichsord++)
  5578.         {   if
  5579.             (   sord[whichsord].possessortype == HERO
  5580.              && sord[whichsord].possessor == whichcounter
  5581.             )
  5582.             {   ok = TRUE;
  5583.                 counterrow = TRUE;
  5584.                 strcat(line[LEFTSIDE][11], sord[whichsord].name);
  5585.                 break; // for speed
  5586.         }   }
  5587.         if (!ok)
  5588.         {   strcat(line[LEFTSIDE][11], GetCatalogStr(li.li_Catalog, MSG_NONE, "None"));
  5589.         }
  5590.  
  5591.         strcpy(line[LEFTSIDE][12], GetCatalogStr(li.li_Catalog, MSG_WOUNDED, "Wounded"));
  5592.         strcat(line[LEFTSIDE][12], "?");
  5593.         pad(line[LEFTSIDE][12]);
  5594.         if (hero[whichcounter].wounded)
  5595.         {   strcat(line[LEFTSIDE][12], GetCatalogStr(li.li_Catalog, MSG_YES, "Yes"));
  5596.         } else
  5597.         {   strcat(line[LEFTSIDE][12], GetCatalogStr(li.li_Catalog, MSG_NO, "No"));
  5598.         }
  5599.  
  5600.         print_paralyzed(hero[whichcounter].loseturn, 13);
  5601.  
  5602.         print_hagall(hero[whichcounter].hagall, 14);
  5603.  
  5604.         print_sea(hero[whichcounter].sea, 15);
  5605.  
  5606.         leftlines = 16; // counting from 1
  5607.  
  5608.         strcpy(line[RIGHTSIDE][0], GetCatalogStr(li.li_Catalog, MSG_RECRUITED_JARLS, "Recruited Jarls"));
  5609.         strcat(line[RIGHTSIDE][0], ":");
  5610.  
  5611.         whichline = oldwhichline = 1; // whichline always points to the NEXT line.
  5612.         for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
  5613.         {   if (jarl[whichjarl].alive && jarl[whichjarl].hero == whichcounter)
  5614.             {   strcpy(line[RIGHTSIDE][whichline], " ");
  5615.                 strcat(line[RIGHTSIDE][whichline], jarl[whichjarl].name);
  5616.                 strcat(line[RIGHTSIDE][whichline], " (");
  5617.                 stcl_d(numberstring, jarl[whichjarl].strength);
  5618.                 strcat(line[RIGHTSIDE][whichline], numberstring);
  5619.                 strcat(line[RIGHTSIDE][whichline], "-");
  5620.                 stcl_d(numberstring, jarl[whichjarl].moves);
  5621.                 strcat(line[RIGHTSIDE][whichline], numberstring);
  5622.                 strcat(line[RIGHTSIDE][whichline], ")");
  5623.                 whichline++;
  5624.         }   }
  5625.         if (whichline == oldwhichline)
  5626.         {   strcpy(line[RIGHTSIDE][whichline], " ");
  5627.             strcat(line[RIGHTSIDE][whichline], GetCatalogStr(li.li_Catalog, MSG_NONE, "None"));
  5628.             whichline++;
  5629.         }
  5630.  
  5631.         strcpy(line[RIGHTSIDE][whichline], "");
  5632.         whichline++;
  5633.         strcpy(line[RIGHTSIDE][whichline], GetCatalogStr(li.li_Catalog, MSG_CONQUERED_KINGDOMS, "Conquered Kingdoms"));
  5634.         strcat(line[RIGHTSIDE][whichline], ":");
  5635.         whichline++;
  5636.  
  5637.         oldwhichline = whichline;
  5638.         for (whichcountry = 0; whichcountry <= 35; whichcountry++)
  5639.         {   if (world[whichcountry].hero == whichcounter)
  5640.             {   strcpy(line[RIGHTSIDE][whichline], " ");
  5641.                 strcat(line[RIGHTSIDE][whichline], world[whichcountry].name);
  5642.                 strcat(line[RIGHTSIDE][whichline], " (");
  5643.                 stcl_d(numberstring, world[whichcountry].tax);
  5644.                 strcat(line[RIGHTSIDE][whichline], numberstring);
  5645.                 strcat(line[RIGHTSIDE][whichline], ")");
  5646.                 whichline++;
  5647.         }   }
  5648.         if (whichline == oldwhichline)
  5649.         {   strcpy(line[RIGHTSIDE][whichline], " ");
  5650.             strcat(line[RIGHTSIDE][whichline], GetCatalogStr(li.li_Catalog, MSG_NONE, "None"));
  5651.             whichline++;
  5652.         }
  5653.  
  5654.         strcpy(line[RIGHTSIDE][whichline], "");
  5655.         whichline++;
  5656.         strcpy(line[RIGHTSIDE][whichline], GetCatalogStr(li.li_Catalog, MSG_MAGIC_TREASURES, "Magic Treasures"));
  5657.         strcat(line[RIGHTSIDE][whichline], ":");
  5658.         whichline++;
  5659.  
  5660.         oldwhichline = whichline;
  5661.         for (whichtreasure = 0; whichtreasure <= TREASURES; whichtreasure++)
  5662.         {   if (treasure[whichtreasure].possessortype == HERO
  5663.              && treasure[whichtreasure].possessor     == whichcounter
  5664.             )
  5665.             {   counterrow = TRUE;
  5666.                 strcpy(line[RIGHTSIDE][whichline], " ");
  5667.                 strcat(line[RIGHTSIDE][whichline], treasure[whichtreasure].name);
  5668.                 if (whichtreasure == FREYFAXI)
  5669.                 {   strcat(line[RIGHTSIDE][whichline], " (");
  5670.                     stcl_d(numberstring, faxirides);
  5671.                     strcat(line[RIGHTSIDE][whichline], numberstring);
  5672.                     strcat(line[RIGHTSIDE][whichline], " ");
  5673.                     strcat(line[RIGHTSIDE][whichline], GetCatalogStr(li.li_Catalog, MSG_RIDES2, "rides"));
  5674.                     strcat(line[RIGHTSIDE][whichline], ")");
  5675.                 }
  5676.                 whichline++;
  5677.         }   }
  5678.         if (whichline == oldwhichline)
  5679.         {   strcpy(line[RIGHTSIDE][whichline], " ");
  5680.             strcat(line[RIGHTSIDE][whichline], GetCatalogStr(li.li_Catalog, MSG_NONE, "None"));
  5681.             whichline++;
  5682.         }
  5683.  
  5684.         rightlines = whichline;
  5685.     } elif (countertype == MONSTER)
  5686.     {   strcpy(line[LEFTSIDE][0], GetCatalogStr(li.li_Catalog, MSG_MONSTER_NAME, "Monster Name"));
  5687.         strcat(line[LEFTSIDE][0], ":");
  5688.         pad(line[LEFTSIDE][0]);
  5689.         strcat(line[LEFTSIDE][0], monster[whichcounter].name);
  5690.  
  5691.         strcpy(line[LEFTSIDE][1], GetCatalogStr(li.li_Catalog, MSG_MONSTER_SPECIES, "Monster Species"));
  5692.         strcat(line[LEFTSIDE][1], ":");
  5693.         pad(line[LEFTSIDE][1]);
  5694.         strcat(line[LEFTSIDE][1], monstertypes[monster[whichcounter].species]);
  5695.  
  5696.         strcpy(line[LEFTSIDE][2], GetCatalogStr(li.li_Catalog, MSG_COMBAT_STRENGTH, "Combat Strength"));
  5697.         strcat(line[LEFTSIDE][2], ":");
  5698.         pad(line[LEFTSIDE][2]);
  5699.         stcl_d(numberstring, monster[whichcounter].strength);
  5700.         strcat(line[LEFTSIDE][2], numberstring);
  5701.         
  5702.         strcpy(line[LEFTSIDE][3], GetCatalogStr(li.li_Catalog, MSG_MOVEMENT_FACTOR, "Movement Factor"));
  5703.         strcat(line[LEFTSIDE][3], ":");
  5704.         pad(line[LEFTSIDE][3]);
  5705.         stcl_d(numberstring, monster[whichcounter].moves);
  5706.         strcat(line[LEFTSIDE][3], numberstring);
  5707.         
  5708.         strcpy(line[LEFTSIDE][4], GetCatalogStr(li.li_Catalog, MSG_WEALTH, "Wealth"));
  5709.         strcat(line[LEFTSIDE][4], ":");
  5710.         pad(line[LEFTSIDE][4]);
  5711.         stcl_d(numberstring, monster[whichcounter].wealth);
  5712.         strcat(line[LEFTSIDE][4], numberstring);
  5713.  
  5714.         print_location(monster[whichcounter].where, 5);
  5715.  
  5716.         print_hagall(monster[whichcounter].hagall, 6);
  5717.  
  5718.         print_sea(monster[whichcounter].sea, 7);
  5719.  
  5720.         strcpy(line[LEFTSIDE][8], GetCatalogStr(li.li_Catalog, MSG_TREASURE, "Treasure"));
  5721.         strcat(line[LEFTSIDE][8], "?");
  5722.         pad(line[LEFTSIDE][8]);
  5723.         ok = FALSE;
  5724.         for (whichtreasure = 0; whichtreasure <= TREASURES; whichtreasure++)
  5725.         {   if
  5726.             (   treasure[whichtreasure].possessortype == MONSTER
  5727.              && treasure[whichtreasure].possessor == whichcounter
  5728.             )
  5729.             {   ok = TRUE;
  5730.                 break;
  5731.         }   }
  5732.         if (ok)
  5733.         {   strcat(line[LEFTSIDE][8], GetCatalogStr(li.li_Catalog, MSG_YES, "Yes"));
  5734.         } else
  5735.         {   strcat(line[LEFTSIDE][8], GetCatalogStr(li.li_Catalog, MSG_NO, "No"));
  5736.         }
  5737.  
  5738.         leftlines = 9; // counting from 1
  5739.         rightlines = 0;
  5740.     } elif (countertype == JARL)
  5741.     {   strcpy(line[LEFTSIDE][0], GetCatalogStr(li.li_Catalog, MSG_JARL_NAME, "Jarl Name"));
  5742.         strcat(line[LEFTSIDE][0], ":");
  5743.         pad(line[LEFTSIDE][0]);
  5744.         if (jarl[whichcounter].face == FACEUP)
  5745.         {   strcat(line[LEFTSIDE][0], jarl[whichcounter].name);
  5746.         } else
  5747.         {   strcat(line[LEFTSIDE][0], GetCatalogStr(li.li_Catalog, MSG_UNKNOWN, "Unknown"));
  5748.         }
  5749.  
  5750.         strcpy(line[LEFTSIDE][1], GetCatalogStr(li.li_Catalog, MSG_HERO, "Hero"));
  5751.         strcat(line[LEFTSIDE][1], ":");
  5752.         pad(line[LEFTSIDE][1]);
  5753.         if (jarl[whichcounter].hero == -1)
  5754.         {   strcat(line[LEFTSIDE][1], GetCatalogStr(li.li_Catalog, MSG_KING_NONE, "None"));
  5755.         } else
  5756.         {   strcat(line[LEFTSIDE][1], hero[jarl[whichcounter].hero].name);
  5757.         }
  5758.  
  5759.         strcpy(line[LEFTSIDE][2], GetCatalogStr(li.li_Catalog, MSG_COMBAT_STRENGTH, "Combat Strength"));
  5760.         strcat(line[LEFTSIDE][2], ":");
  5761.         pad(line[LEFTSIDE][2]);
  5762.         stcl_d(numberstring, jarl[whichcounter].strength);
  5763.         strcat(line[LEFTSIDE][2], numberstring);
  5764.       
  5765.         strcpy(line[LEFTSIDE][3], GetCatalogStr(li.li_Catalog, MSG_MOVEMENT_FACTOR, "Movement Factor"));
  5766.         strcat(line[LEFTSIDE][3], ":");
  5767.         pad(line[LEFTSIDE][3]);
  5768.         stcl_d(numberstring, jarl[whichcounter].moves);
  5769.         strcat(line[LEFTSIDE][3], numberstring);
  5770.  
  5771.         strcpy(line[LEFTSIDE][4], GetCatalogStr(li.li_Catalog, MSG_WEALTH, "Wealth"));
  5772.         strcat(line[LEFTSIDE][4], ":");
  5773.         pad(line[LEFTSIDE][4]);
  5774.         stcl_d(numberstring, jarl[whichcounter].wealth);
  5775.         strcat(line[LEFTSIDE][4], numberstring);
  5776.  
  5777.         print_location(jarl[whichcounter].where, 5);
  5778.  
  5779.         strcpy(line[LEFTSIDE][6], GetCatalogStr(li.li_Catalog, MSG_HOMELAND, "Homeland"));
  5780.         strcat(line[LEFTSIDE][6], ":");
  5781.         pad(line[LEFTSIDE][6]);
  5782.         strcat(line[LEFTSIDE][6], world[hero[whichcounter].homewhere].name);
  5783.         strcat(line[LEFTSIDE][6], " (");
  5784.         stcl_d(numberstring, world[hero[whichcounter].homewhere].tax);
  5785.         strcat(line[LEFTSIDE][6], numberstring);
  5786.         strcat(line[LEFTSIDE][6], ")");
  5787.         
  5788.         strcpy(line[LEFTSIDE][7], GetCatalogStr(li.li_Catalog, MSG_SWORD, "Sword"));
  5789.         strcat(line[LEFTSIDE][7], ":");
  5790.         pad(line[LEFTSIDE][7]);
  5791.         ok = FALSE;
  5792.         for (whichsord = 0; whichsord <= SORDS; whichsord++)
  5793.         {   if
  5794.             (   sord[whichsord].possessortype == JARL
  5795.              && sord[whichsord].possessor == whichcounter
  5796.             )
  5797.             {   ok = TRUE;
  5798.                 counterrow = TRUE;
  5799.                 strcat(line[LEFTSIDE][7], sord[whichsord].name);
  5800.                 break; // for speed
  5801.         }   }
  5802.         if (!ok)
  5803.         {   strcat(line[LEFTSIDE][7], GetCatalogStr(li.li_Catalog, MSG_NONE, "None"));
  5804.         }
  5805.  
  5806.         print_paralyzed(jarl[whichcounter].loseturn, 8);
  5807.  
  5808.         print_hagall(jarl[whichcounter].where, 9);
  5809.  
  5810.         print_sea(jarl[whichcounter].sea, 10);
  5811.  
  5812.         leftlines = 11; // counting from 1
  5813.  
  5814.         strcpy(line[RIGHTSIDE][0], GetCatalogStr(li.li_Catalog, MSG_MAGIC_TREASURES, "Magic Treasures"));
  5815.         strcat(line[RIGHTSIDE][0], ":");
  5816.         whichline = oldwhichline = 1; // whichline always points to the NEXT line.
  5817.         for (whichtreasure = 0; whichtreasure <= TREASURES; whichtreasure++)
  5818.         {   if (treasure[whichtreasure].possessortype == JARL
  5819.              && treasure[whichtreasure].possessor     == whichcounter
  5820.             )
  5821.             {   counterrow = TRUE;
  5822.                 strcpy(line[RIGHTSIDE][whichline], " ");
  5823.                 strcat(line[RIGHTSIDE][whichline], treasure[whichtreasure].name);
  5824.                 if (whichtreasure == FREYFAXI)
  5825.                 {   strcat(line[RIGHTSIDE][whichline], " (");
  5826.                     stcl_d(numberstring, faxirides);
  5827.                     strcat(line[RIGHTSIDE][whichline], numberstring);
  5828.                     strcat(line[RIGHTSIDE][whichline], " ");
  5829.                     strcat(line[RIGHTSIDE][whichline], GetCatalogStr(li.li_Catalog, MSG_RIDES2, "rides"));
  5830.                     strcat(line[RIGHTSIDE][whichline], ")");
  5831.                 }
  5832.                 whichline++;
  5833.         }   }
  5834.         if (whichline == oldwhichline)
  5835.         {   strcpy(line[RIGHTSIDE][whichline], " ");
  5836.             strcat(line[RIGHTSIDE][whichline], GetCatalogStr(li.li_Catalog, MSG_NONE, "None"));
  5837.             whichline++;
  5838.         }
  5839.  
  5840.         rightlines = whichline;
  5841.     } elif (countertype == TREASURE)
  5842.     {   strcpy(line[LEFTSIDE][0], GetCatalogStr(li.li_Catalog, MSG_TREASURE_NAME, "Treasure Name"));
  5843.         strcat(line[LEFTSIDE][0], ":");
  5844.         pad(line[LEFTSIDE][0]);
  5845.         strcat(line[LEFTSIDE][0], treasure[whichcounter].name);
  5846.  
  5847.         print_location(treasure[whichcounter].where, 1);
  5848.  
  5849.         strcpy(line[LEFTSIDE][2], GetCatalogStr(li.li_Catalog, MSG_RIDES, "Rides"));
  5850.         strcat(line[LEFTSIDE][2], ":");
  5851.         if (whichcounter == FREYFAXI)
  5852.         {   // assert(faxirides != -1);
  5853.             stcl_d(numberstring, faxirides);
  5854.             strcat(line[LEFTSIDE][2], numberstring);
  5855.         } else
  5856.         {   strcat(line[LEFTSIDE][2], GetCatalogStr(li.li_Catalog, MSG_N_A, "n/a"));
  5857.         }
  5858.  
  5859.         leftlines = 3;
  5860.         rightlines = 0;
  5861.     } elif (countertype == KINGDOM)
  5862.     {   strcpy(line[LEFTSIDE][0], GetCatalogStr(li.li_Catalog, MSG_KINGDOM_NAME, "Kingdom Name"));
  5863.         strcat(line[LEFTSIDE][0], ":");
  5864.         pad(line[LEFTSIDE][0]);
  5865.         strcat(line[LEFTSIDE][0], world[whichcounter].name);
  5866.  
  5867.         strcpy(line[LEFTSIDE][1], GetCatalogStr(li.li_Catalog, MSG_KING, "King"));
  5868.         strcat(line[LEFTSIDE][1], ":");
  5869.         pad(line[LEFTSIDE][1]);
  5870.         if (world[whichcounter].hero == -1)
  5871.         {   strcat(line[LEFTSIDE][1], GetCatalogStr(li.li_Catalog, MSG_KING_NONE, "None"));
  5872.         } else
  5873.         {   strcat(line[LEFTSIDE][1], hero[world[whichcounter].hero].name);
  5874.         }
  5875.  
  5876.         strcpy(line[LEFTSIDE][2], GetCatalogStr(li.li_Catalog, MSG_TAXATION_FACTOR, "Taxation Factor"));
  5877.         strcat(line[LEFTSIDE][2], ":");
  5878.         pad(line[LEFTSIDE][2]);
  5879.         stcl_d(numberstring, world[whichcounter].tax);
  5880.         strcat(line[LEFTSIDE][2], numberstring);
  5881.  
  5882.         strcpy(line[LEFTSIDE][3], GetCatalogStr(li.li_Catalog, MSG_TYPE, "Type"));
  5883.         strcat(line[LEFTSIDE][3], ":");
  5884.         pad(line[LEFTSIDE][3]);
  5885.         if (world[whichcounter].type == LAND)
  5886.         {   strcat(line[LEFTSIDE][3], GetCatalogStr(li.li_Catalog, MSG_LAND, "Land"));
  5887.         } elif (world[whichcounter].type == ISLE)
  5888.         {   strcat(line[LEFTSIDE][3], GetCatalogStr(li.li_Catalog, MSG_ISLAND, "Island"));
  5889.         } elif (world[whichcounter].type == SEA)
  5890.         {   strcat(line[LEFTSIDE][3], GetCatalogStr(li.li_Catalog, MSG_SEA, "Sea"));
  5891.         } else
  5892.         {   // assert(world[whichcounter].type == PENINSULA);
  5893.             strcat(line[LEFTSIDE][3], GetCatalogStr(li.li_Catalog, MSG_PENINSULA, "Peninsula"));
  5894.         }
  5895.  
  5896.         strcpy(line[LEFTSIDE][4], "Is (");
  5897.         strcat(line[LEFTSIDE][4], GetCatalogStr(li.li_Catalog, MSG_ICE, "ice"));
  5898.         strcat(line[LEFTSIDE][4], ")?");
  5899.         pad(line[LEFTSIDE][4]);
  5900.         if (world[whichcounter].is)
  5901.         {   strcat(line[LEFTSIDE][4], GetCatalogStr(li.li_Catalog, MSG_YES, "Yes"));
  5902.         } else
  5903.         {   strcat(line[LEFTSIDE][4], GetCatalogStr(li.li_Catalog, MSG_NO, "No"));
  5904.         }
  5905.                                    
  5906.         leftlines = 5; // counting from 1
  5907.  
  5908.         strcpy(line[RIGHTSIDE][0], GetCatalogStr(li.li_Catalog, MSG_CONTENTS, "Contents"));
  5909.         strcat(line[RIGHTSIDE][0], ":");
  5910.  
  5911.         whichline = oldwhichline = 1; // whichline always points to the NEXT line.
  5912.         for (whichhero = 0; whichhero <= HEROES; whichhero++)
  5913.         {   if (hero[whichhero].alive && hero[whichhero].where == whichcounter)
  5914.             {   strcpy(line[RIGHTSIDE][whichline], " ");
  5915.                 strcat(line[RIGHTSIDE][whichline], GetCatalogStr(li.li_Catalog, MSG_HERO, "Hero"));
  5916.                 strcat(line[RIGHTSIDE][whichline], " ");
  5917.                 strcat(line[RIGHTSIDE][whichline], hero[whichhero].name);
  5918.                 strcat(line[RIGHTSIDE][whichline], " (");
  5919.                 stcl_d(numberstring, hero[whichhero].strength);
  5920.                 strcat(line[RIGHTSIDE][whichline], numberstring);
  5921.                 strcat(line[RIGHTSIDE][whichline], "-");
  5922.                 stcl_d(numberstring, hero[whichhero].moves);
  5923.                 strcat(line[RIGHTSIDE][whichline], numberstring);
  5924.                 strcat(line[RIGHTSIDE][whichline], ")");
  5925.                 whichline++;
  5926.         }   }
  5927.         for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
  5928.         {   if (jarl[whichjarl].alive && jarl[whichjarl].where == whichcounter)
  5929.             {   strcpy(line[RIGHTSIDE][whichline], " ");
  5930.                 if (jarl[whichjarl].face == FACEUP)
  5931.                 {   strcat(line[RIGHTSIDE][whichline], GetCatalogStr(li.li_Catalog, MSG_JARL, "Jarl"));
  5932.                     strcat(line[RIGHTSIDE][whichline], " ");
  5933.                     strcat(line[RIGHTSIDE][whichline], jarl[whichjarl].name);
  5934.                     strcat(line[RIGHTSIDE][whichline], " (");
  5935.                     stcl_d(numberstring, jarl[whichjarl].strength);
  5936.                     strcat(line[RIGHTSIDE][whichline], numberstring);
  5937.                     strcat(line[RIGHTSIDE][whichline], "-");
  5938.                     stcl_d(numberstring, jarl[whichjarl].moves);
  5939.                     strcat(line[RIGHTSIDE][whichline], numberstring);
  5940.                     strcat(line[RIGHTSIDE][whichline], ")");
  5941.                 } else
  5942.                 {   strcat(line[RIGHTSIDE][whichline], GetCatalogStr(li.li_Catalog, MSG_UNKNOWN_JARL, "Unknown jarl"));
  5943.                     strcat(line[RIGHTSIDE][whichline], " (?-?)");
  5944.                 }
  5945.                 whichline++;
  5946.         }   }
  5947.         for (whichmonster = 0; whichmonster <= MONSTERS; whichmonster++)
  5948.         {   if (monster[whichmonster].alive && monster[whichmonster].where == whichcounter)
  5949.             {   strcpy(line[RIGHTSIDE][whichline], " ");
  5950.                 strcat(line[RIGHTSIDE][whichline], monstertypes[monster[whichmonster].species]);
  5951.                 strcat(line[RIGHTSIDE][whichline], " ");
  5952.                 strcat(line[RIGHTSIDE][whichline], monster[whichmonster].name);
  5953.                 strcat(line[RIGHTSIDE][whichline], " (");
  5954.                 stcl_d(numberstring, monster[whichmonster].strength);
  5955.                 strcat(line[RIGHTSIDE][whichline], numberstring);
  5956.                 strcat(line[RIGHTSIDE][whichline], "-");
  5957.                 stcl_d(numberstring, monster[whichmonster].moves);
  5958.                 strcat(line[RIGHTSIDE][whichline], numberstring);
  5959.                 strcat(line[RIGHTSIDE][whichline], ")");
  5960.                 whichline++;
  5961.         }   }
  5962.         for (whichtreasure = 0; whichtreasure <= TREASURES; whichtreasure++)
  5963.         {   if
  5964.             (   treasure[whichtreasure].possessortype == KINGDOM
  5965.              && treasure[whichtreasure].where == whichcounter
  5966.             )
  5967.             {   strcpy(line[RIGHTSIDE][whichline], " ");
  5968.                 strcat(line[RIGHTSIDE][whichline], GetCatalogStr(li.li_Catalog, MSG_THE, "The"));
  5969.                 strcat(line[RIGHTSIDE][whichline], " ");
  5970.                 strcat(line[RIGHTSIDE][whichline], treasure[whichtreasure].name);
  5971.                 whichline++;
  5972.         }   }
  5973.         for (whichsord = 0; whichsord <= SORDS; whichsord++)
  5974.         {   if
  5975.             (   sord[whichsord].possessortype == KINGDOM
  5976.              && sord[whichsord].where == whichcounter
  5977.             )
  5978.             {   strcpy(line[RIGHTSIDE][whichline], " ");
  5979.                 strcat(line[RIGHTSIDE][whichline], GetCatalogStr(li.li_Catalog, MSG_SWORD, "Sword"));
  5980.                 strcat(line[RIGHTSIDE][whichline], " ");
  5981.                 strcat(line[RIGHTSIDE][whichline], sord[whichsord].name);
  5982.                 whichline++;
  5983.         }   }
  5984.  
  5985.         if (whichline == oldwhichline)
  5986.         {   strcpy(line[RIGHTSIDE][whichline], " ");
  5987.             strcat(line[RIGHTSIDE][whichline], GetCatalogStr(li.li_Catalog, MSG_NONE, "None"));
  5988.             whichline++;
  5989.         }
  5990.  
  5991.         rightlines = whichline;
  5992.     } elif (countertype == SORD)
  5993.     {   strcpy(line[LEFTSIDE][0], GetCatalogStr(li.li_Catalog, MSG_SWORD_NAME, "Sword Name"));
  5994.         strcat(line[LEFTSIDE][0], ":");
  5995.         pad(line[LEFTSIDE][0]);
  5996.         strcat(line[LEFTSIDE][0], sord[whichcounter].name);
  5997.  
  5998.         print_location(sord[whichcounter].where, 1);
  5999.  
  6000.         leftlines = 2; // counting from 1
  6001.         rightlines = 0;
  6002.     }
  6003.  
  6004.     if (leftlines >= rightlines)
  6005.     {   lines = leftlines;
  6006.     } else
  6007.     {   lines = rightlines;
  6008.     }
  6009.     if (rightlines > 0)
  6010.     {   wide = 1;
  6011.     } else
  6012.     {   wide = 0;
  6013.     }
  6014.  
  6015.     if (!(InfoWindowPtr = (struct Window *) OpenWindowTags(NULL,
  6016.         WA_Left,          (SCREENXPIXEL / 2) - ((360 + (280 * wide )) / 2),
  6017.         WA_Top,           (SCREENYPIXEL / 2) - ( (30 + ( 10 * lines)) / 2),
  6018.         WA_Width,         320 + (320 * wide ),
  6019.         WA_Height,         30 + ( 10 * lines),
  6020.         WA_IDCMP,         IDCMP_CLOSEWINDOW | IDCMP_RAWKEY,
  6021.         WA_Title,         GetCatalogStr(li.li_Catalog, MSG_INFORMATION, "Information"),
  6022.         WA_Gadgets,       NULL,
  6023.         WA_CustomScreen,  ScreenPtr,
  6024.         WA_DragBar,       TRUE,
  6025.         WA_CloseGadget,   TRUE,
  6026.         WA_NoCareRefresh, TRUE,
  6027.         WA_Activate,      TRUE,
  6028.     TAG_DONE))
  6029.     )
  6030.     {   DisplayAlert(AT_Recovery, "\0\20\20Saga: Can't open information window!\0", 24);
  6031.         cleanexit(EXIT_FAILURE);
  6032.     }
  6033.     /* if (countertype == HERO)
  6034.     {   SetAPen(InfoWindowPtr->RPort, herocolour[whichcounter]);
  6035.     } elif (countertype == JARL && jarl[counter].hero != -1)
  6036.     {   SetAPen(InfoWindowPtr->RPort, herocolour[jarl[whichcounter].hero]);
  6037.     } elif (countertype == KINGDOM && world[counter].hero != -1)
  6038.     {   SetAPen(InfoWindowPtr->RPort, herocolour[world[whichcounter].hero]);
  6039.     } if we had a free pen, we could do this... else
  6040.     {   */ SetAPen(InfoWindowPtr->RPort, LIGHTGREY);
  6041.  /* } */
  6042.     RectFill(InfoWindowPtr->RPort, 8, 13, 320 + (320 * wide) - 10, 30 + (10 * lines) - 6);
  6043.     SetAPen(InfoWindowPtr->RPort, BLACK);
  6044.     SetDrMd(InfoWindowPtr->RPort, JAM1);
  6045.  
  6046.     for (whichline = 0; whichline < leftlines; whichline++)
  6047.     {   Move(InfoWindowPtr->RPort, 16, 26 + (whichline * 10));
  6048.         Text(InfoWindowPtr->RPort, line[LEFTSIDE][whichline], strlen(line[LEFTSIDE][whichline]));
  6049.     }
  6050.     if (wide)
  6051.     {   for (whichline = 0; whichline < rightlines; whichline++)
  6052.         {   Move(InfoWindowPtr->RPort, 320 + 16, 26 + (whichline * 10));
  6053.             Text(InfoWindowPtr->RPort, line[RIGHTSIDE][whichline], strlen(line[RIGHTSIDE][whichline]));
  6054.     }   }
  6055.  
  6056.     if (counterrow)
  6057.     {   if (countertype == HERO)
  6058.         {   hero_info(whichcounter);
  6059.         } else
  6060.         {   assert(countertype == JARL);
  6061.             jarl_info(whichcounter);
  6062.     }   }
  6063.  
  6064.     while(!done)
  6065.     {   Wait(1L << InfoWindowPtr->UserPort->mp_SigBit);
  6066.         while (MsgPtr = (struct IntuiMessage *) GetMsg(InfoWindowPtr->UserPort))
  6067.         {   class  = MsgPtr->Class;
  6068.             code   = MsgPtr->Code;
  6069.             qual   = MsgPtr->Qualifier;
  6070.             ReplyMsg((struct Message *) MsgPtr);
  6071.             switch(class)
  6072.             {
  6073.             case IDCMP_CLOSEWINDOW:
  6074.                 done = TRUE;
  6075.             break;
  6076.             case IDCMP_RAWKEY:
  6077.                 if (!(qual & IEQUALIFIER_REPEAT) && code < KEYUP && (code < FIRSTQUALIFIER || code > LASTQUALIFIER))
  6078.                 {   done = TRUE;
  6079.                 }
  6080.             break;
  6081.             default:
  6082.             break;
  6083.     }   }   }
  6084.  
  6085.     if (counterrow)
  6086.     {   uninfo();
  6087.     }
  6088.     CloseWindow(InfoWindowPtr);
  6089.     InfoWindowPtr = NULL;
  6090.     clearkybd();
  6091. }
  6092.  
  6093. MODULE void getdefender(SLONG attackhero, SLONG here)
  6094. {   FLAG  done = FALSE;
  6095.     SLONG counter, countertype, defendtype, defender, whichattack,
  6096.           whichjarl;
  6097.  
  6098.     do
  6099.     {   saywho(HERO, attackhero, TRUE, FALSE);
  6100.         strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_SELECT_DEFENDER, "select defender"));
  6101.         strcat(saystring, "?");
  6102.         say(LOWER);
  6103.  
  6104.         counter = getevent(COUNTER, &countertype);
  6105.         if (counter == -2 || counter == -3)
  6106.         {   // user wants to quit (back to `select attacker')
  6107.             if (hero[attackhero].attacking)
  6108.             {   deselect_hero(attackhero, TRUE);
  6109.             }
  6110.             for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
  6111.             {   if (jarl[whichjarl].alive && jarl[whichjarl].attacking)
  6112.                 {   deselect_jarl(whichjarl);
  6113.             }   }
  6114.             return;
  6115.         } elif (countertype == HERO) // if an enemy hero
  6116.         {   if (counter != attackhero && hero[counter].where == here)
  6117.             {   defendtype = HERO;
  6118.                 defender = counter;
  6119.                 done = TRUE;
  6120.         }   }
  6121.         elif (countertype == JARL) // if an enemy jarl
  6122.         {   if (jarl[counter].hero != attackhero && jarl[counter].where == here)
  6123.             {   defendtype = JARL;
  6124.                 defender = counter;
  6125.                 done = TRUE;
  6126.         }   }
  6127.         elif (countertype == MONSTER) // if a monster
  6128.         {   if (monster[counter].where == here)
  6129.             {   defendtype = MONSTER;
  6130.                 defender = counter;
  6131.                 done = TRUE;
  6132.         }   }
  6133.         elif (countertype == KINGDOM)
  6134.         {   if
  6135.             (    world[counter].hero != attackhero
  6136.               && counter <= 35
  6137.               && counter == here
  6138.             )
  6139.             {   defendtype = KINGDOM;
  6140.                 defender = counter;
  6141.                 done = TRUE;
  6142.         }   }
  6143.  
  6144.         if (done)
  6145.         {   if (hero[attackhero].attacking)
  6146.             {   // check if the hero has already fought this
  6147.                 for (whichattack = 0; whichattack <= ATTACKS; whichattack++)
  6148.                 {   if
  6149.                     (   hero[attackhero].attacktype[whichattack] == countertype
  6150.                      && hero[attackhero].attacked[whichattack]   == counter
  6151.                     )
  6152.                     {   done = FALSE;
  6153.  
  6154.                         saywho(HERO, attackhero, FALSE, FALSE);
  6155.                         strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_H_A_F_T_T_T, "has already fought that this turn"));
  6156.                         strcat(saystring, ".");
  6157.                         say(LOWER);
  6158.                         anykey();
  6159.                         break; // for speed
  6160.             }   }   }
  6161.             for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
  6162.             {   if (jarl[whichjarl].attacking)
  6163.                 {   for (whichattack = 0; whichattack <= ATTACKS; whichattack++)
  6164.                     {   if
  6165.                         (   jarl[whichjarl].attacktype[whichattack] == countertype
  6166.                          && jarl[whichjarl].attacked[whichattack]   == counter
  6167.                         )
  6168.                         {   done = FALSE;
  6169.  
  6170.                             saywho(JARL, whichjarl, FALSE, FALSE);
  6171.                             strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_H_A_F_T_T_T, "has already fought that this turn"));
  6172.                             strcat(saystring, ".");
  6173.                             say(LOWER);
  6174.                             anykey();
  6175.                             break; // for speed
  6176.         }   }   }   }   }
  6177.         else
  6178.         {   ; // DisplayBeep(ScreenPtr);
  6179.     }   }
  6180.     while (!done);
  6181.  
  6182.     // ok, going ahead with the battle
  6183.     if (countertype == JARL && jarl[counter].face == FACEDOWN)
  6184.     {   revealjarl(counter, TRUE);
  6185.     }
  6186.     if (hero[attackhero].attacking)
  6187.     {   for (whichattack = 0; whichattack <= ATTACKS; whichattack++)
  6188.         {   if (hero[attackhero].attacktype[whichattack] == -1)
  6189.             {   hero[attackhero].attacktype[whichattack] = countertype;
  6190.                 hero[attackhero].attacked[whichattack]   = counter;
  6191.                 break;
  6192.     }   }   }
  6193.     for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
  6194.     {   if (jarl[whichjarl].attacking)
  6195.         {   for (whichattack = 0; whichattack <= ATTACKS; whichattack++)
  6196.             {   if (jarl[whichjarl].attacktype[whichattack] == -1)
  6197.                 {   jarl[whichjarl].attacktype[whichattack] = countertype;
  6198.                     jarl[whichjarl].attacked[whichattack]   = counter;
  6199.                     break;
  6200.     }   }   }   }
  6201.  
  6202.     dobattle(countertype, counter, attackhero);
  6203. }
  6204.  
  6205. MODULE FLAG needsord(SLONG countertype, SLONG counter)
  6206. {   SLONG whichsord;
  6207.  
  6208.     for (whichsord = 0; whichsord <= SORDS; whichsord++)
  6209.     {   if
  6210.         (   sord[whichsord].possessortype == countertype
  6211.          && sord[whichsord].possessor == counter
  6212.         )
  6213.         {   return(FALSE);
  6214.     }   }
  6215.     return(TRUE);
  6216. }
  6217.  
  6218. MODULE void brosung(SLONG countertype, SLONG whichcounter)
  6219. {   SLONG result, whichconnection, whichmonster, whichtreasure, where;
  6220.    
  6221.     for (whichconnection = 0; whichconnection <= CONNECTIONS; whichconnection++)
  6222.     {   if (countertype == HERO)
  6223.         {   where = world[hero[whichcounter].where].connection[whichconnection];
  6224.         } else
  6225.         {   assert(countertype == JARL);
  6226.             where = world[jarl[whichcounter].where].connection[whichconnection];
  6227.         }
  6228.         if (where == -1)
  6229.         {   break;
  6230.         }
  6231.         for (whichmonster = 0; whichmonster <= MONSTERS; whichmonster++)
  6232.         {   if
  6233.             (   monster[whichmonster].alive
  6234.              && monster[whichmonster].species == DRAGON
  6235.              && monster[whichmonster].where == where
  6236.             )
  6237.             {   // there is a dragon here
  6238.                 for (whichtreasure = 0; whichtreasure <= TREASURES; whichtreasure++)
  6239.                 {   if
  6240.                     (   treasure[whichtreasure].possessortype == MONSTER
  6241.                      && treasure[whichtreasure].possessor == whichmonster
  6242.                     )
  6243.                     {   /* We know it is human control because we
  6244.                            don't call this function for Amiga heroes/jarls */
  6245.  
  6246.                         saywho(countertype, whichcounter, TRUE, FALSE);
  6247.                         strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_EXCHANGE_THE, "exchange the"));
  6248.                         strcat(saystring, " ");
  6249.                         strcat(saystring, treasure[BROSUNGNECKLACE].name);
  6250.                         strcat(saystring, " ");
  6251.                         strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_WITH, "with"));
  6252.                         strcat(saystring, " ");
  6253.                         strcat(saystring, monstertypes[DRAGON]);
  6254.                         strcat(saystring, " ");
  6255.                         strcat(saystring, monster[whichmonster].name);
  6256.                         strcat(saystring, " (");
  6257.                         strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_CHAR_YES, "Y"));
  6258.                         strcat(saystring, "/");
  6259.                         strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_CHAR_NO, "N"));
  6260.                         strcat(saystring, ")?");
  6261.                         say(LOWER);
  6262.                         do
  6263.                         {   result = getevent(KEYBOARD, NULL);
  6264.                         } while (result != onekey[ONEKEY_YES] && result != onekey[ONEKEY_NO]);
  6265.                         if (result == onekey[ONEKEY_YES])
  6266.                         {   // give the dragon's treasure to the hero/jarl
  6267.                             treasure[whichtreasure].possessortype   = countertype;
  6268.                             treasure[whichtreasure].possessor       = whichcounter;
  6269.  
  6270.                             saywho(countertype, whichcounter, TRUE, FALSE);
  6271.                             strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_TAKES_THE, "takes the"));
  6272.                             strcat(saystring, " ");
  6273.                             strcat(saystring, treasure[whichtreasure].name);
  6274.                             strcat(saystring, ".");
  6275.                             say(LOWER);
  6276.  
  6277.                             // give the hero/jarl's treasure to the dragon
  6278.                             treasure[BROSUNGNECKLACE].possessortype = MONSTER;
  6279.                             treasure[BROSUNGNECKLACE].possessor     = whichmonster;
  6280.                             break;
  6281. }   }   }   }   }   }   }
  6282.  
  6283. MODULE void flash(SLONG country)
  6284. {   SLONG colour;
  6285.  
  6286.     if (country < 0 || country > 65)
  6287.     {   return;
  6288.     }
  6289.  
  6290.     if (country == 9)
  6291.     {   colour = 89; // Suder Gotland
  6292.     } elif (country == 10)
  6293.     {   colour = 90; // Juteland
  6294.     } elif (country == 11)
  6295.     {   colour = 91; // Scandia
  6296.     } else
  6297.     {   colour = country + 8;
  6298.     }
  6299.  
  6300.     SetRGB4(&ScreenPtr->ViewPort, colour, 15, 15, 15); // white flash
  6301.     Delay(2); // hold the flash
  6302.  
  6303.     if (country >= 36)
  6304.     {   SetRGB4(&ScreenPtr->ViewPort, colour,  0,  0,  9); // dark blue
  6305.     } elif (world[country].hero != -1)
  6306.     {   SetRGB4
  6307.         (   &ScreenPtr->ViewPort,
  6308.             colour,
  6309.             herocolour[world[country].hero].red,
  6310.             herocolour[world[country].hero].green,
  6311.             herocolour[world[country].hero].blue
  6312.         );
  6313.     } elif (world[country].is)
  6314.     {   SetRGB4(&ScreenPtr->ViewPort, colour, 12, 12, 12); // light grey ice
  6315.     } else
  6316.     {   SetRGB4
  6317.         (   &ScreenPtr->ViewPort,
  6318.             colour,
  6319.             taxcolours[world[country].tax].red,
  6320.             taxcolours[world[country].tax].green,
  6321.             taxcolours[world[country].tax].blue
  6322.         );
  6323. }   }
  6324.  
  6325. MODULE FLAG assess(SLONG countertype, SLONG counter)
  6326. {   return(FALSE);
  6327. }
  6328.  
  6329. MODULE void promote(SLONG whichhero, SLONG whichjarl)
  6330. {   remove_jarl(whichjarl, TRUE);
  6331.     jarl[whichjarl].alive     = FALSE;
  6332.     hero[whichhero].alive     = TRUE;
  6333.     hero[whichhero].promoted  = whichjarl;
  6334.     hero[whichhero].name      = jarl[whichjarl].name;
  6335.     hero[whichhero].moves     = jarl[whichjarl].moves;
  6336.     hero[whichhero].strength  = jarl[whichjarl].strength;
  6337.     hero[whichhero].where     = jarl[whichjarl].where;
  6338.     hero[whichhero].homewhere = jarl[whichjarl].homewhere;
  6339.     hero[whichhero].god       =
  6340.     hero[whichhero].rune      = -1;
  6341.     hero[whichhero].maidens   =
  6342.     hero[whichhero].glory     = 0;
  6343.     hero[whichhero].hagall    = jarl[whichjarl].hagall;
  6344.     hero[whichhero].loseturn  = jarl[whichjarl].loseturn;
  6345.     hero[whichhero].wealth    = jarl[whichjarl].wealth;
  6346.     hero[whichhero].wounded   = FALSE;
  6347.     deselect_hero(whichhero, TRUE);
  6348.     move_hero(whichhero, TRUE);
  6349. }
  6350.  
  6351. MODULE void withdraw(SLONG whichhero)
  6352. {   SLONG whichcountry, whichjarl;
  6353.  
  6354.     hero[whichhero].verydead = TRUE;
  6355.  
  6356.     // all the jarls of the dead hero are freed
  6357.     for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
  6358.     {   if (jarl[whichjarl].alive && jarl[whichjarl].hero == whichhero)
  6359.         {   jarl[whichjarl].hero = -1;
  6360.     }   }
  6361.  
  6362.     // all the kingdoms of the dead hero declare independence
  6363.     for (whichcountry = 0; whichcountry <= 35; whichcountry++)
  6364.     {   if (world[whichcountry].hero == whichhero)
  6365.         {   world[whichcountry].hero = -1;
  6366.     }   }
  6367.  
  6368.     darken();
  6369. }
  6370.  
  6371. MODULE FLAG asksord(SLONG countertype, SLONG counter, SLONG whichsord)
  6372. {   SLONG result, whichcountry;
  6373.  
  6374.     if (countertype == JARL)
  6375.     {   whichcountry = jarl[counter].where;
  6376.     } else
  6377.     {   whichcountry = hero[counter].where;
  6378.     }
  6379.  
  6380.     saywho(countertype, counter, FALSE, FALSE);
  6381.     strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_IN, "in"));
  6382.     strcat(saystring, " ");
  6383.     strcat(saystring, world[whichcountry].name);
  6384.     strcat(saystring, ", ");
  6385.     strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_TAKE_SWORD, "take sword"));
  6386.     strcat(saystring, " ");
  6387.     strcat(saystring, sord[whichsord].name);
  6388.     strcat(saystring, " (");
  6389.     strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_CHAR_YES, "Y"));
  6390.     strcat(saystring, "/");
  6391.     strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_CHAR_NO, "N"));
  6392.     strcat(saystring, ")?");
  6393.     say(LOWER);
  6394.     do
  6395.     {   result = getevent(KEYBOARD, NULL);
  6396.     } while (result != onekey[ONEKEY_YES] && result != onekey[ONEKEY_NO]);
  6397.     if (result == onekey[ONEKEY_YES])
  6398.     {   remove_sord(whichsord, TRUE);
  6399.         sord[whichsord].possessortype = countertype;
  6400.         sord[whichsord].possessor     = counter;
  6401.         sord[whichsord].where         = -1;
  6402.         return(TRUE);
  6403.     }
  6404.     // assert(result == onekey[ONEKEY_NO]);
  6405.     return(FALSE);
  6406. }
  6407.  
  6408.  
  6409. MODULE void asktreasure(SLONG countertype, SLONG counter, SLONG whichtreasure)
  6410. {   SLONG result, whichcountry;
  6411.  
  6412.     if (countertype == JARL)
  6413.     {   whichcountry = jarl[counter].where;
  6414.     } else
  6415.     {   whichcountry = hero[counter].where;
  6416.     }
  6417.  
  6418.     saywho(countertype, counter, FALSE, FALSE);
  6419.     strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_IN, "in"));
  6420.     strcat(saystring, " ");
  6421.     strcat(saystring, world[whichcountry].name);
  6422.     strcat(saystring, ", ");
  6423.     strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_TAKE_THE, "take the"));
  6424.     strcat(saystring, " ");
  6425.     strcat(saystring, treasure[whichtreasure].name);
  6426.     strcat(saystring, " (");
  6427.     strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_CHAR_YES, "Y"));
  6428.     strcat(saystring, "/");
  6429.     strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_CHAR_NO, "N"));
  6430.     strcat(saystring, ")?");
  6431.     say(LOWER);
  6432.     do
  6433.     {   result = getevent(KEYBOARD, NULL);
  6434.     } while (result != onekey[ONEKEY_YES] && result != onekey[ONEKEY_NO]);
  6435.     if (result == onekey[ONEKEY_YES])
  6436.     {   remove_treasure(whichtreasure, TRUE);
  6437.         treasure[whichtreasure].possessortype = countertype;
  6438.         treasure[whichtreasure].possessor     = counter;
  6439.         treasure[whichtreasure].where         = -1;
  6440. }   }
  6441.  
  6442. MODULE void pad(STRPTR thestring)
  6443. {   SLONG i, length;
  6444.  
  6445.     length = strlen(thestring);
  6446.  
  6447.     if (length < 21)
  6448.     {   for (i = length; i <= 21; i++)
  6449.         {   strcat(thestring, " ");
  6450. }   }   }
  6451.  
  6452. MODULE void print_location(SLONG whichcountry, SLONG index)
  6453. {   strcpy(line[LEFTSIDE][index], GetCatalogStr(li.li_Catalog, MSG_LOCATION, "Location"));
  6454.     strcat(line[LEFTSIDE][index], ":");
  6455.     pad(line[LEFTSIDE][index]);
  6456.     strcat(line[LEFTSIDE][index], world[whichcountry].name);
  6457.     strcat(line[LEFTSIDE][index], " (");
  6458.     stcl_d(numberstring, world[whichcountry].tax);
  6459.     strcat(line[LEFTSIDE][index], numberstring);
  6460.     strcat(line[LEFTSIDE][index], ")");
  6461. }
  6462.  
  6463. MODULE void print_sea(SLONG sea_value, SLONG index)
  6464. {   strcpy(line[LEFTSIDE][index], GetCatalogStr(li.li_Catalog, MSG_MOVE_BY_SEA, "Move by sea"));
  6465.     strcat(line[LEFTSIDE][index], "?");
  6466.     pad(line[LEFTSIDE][index]);
  6467.     if (sea_value == NORMAL)
  6468.     {   strcat(line[LEFTSIDE][index], GetCatalogStr(li.li_Catalog, MSG_YES, "Yes"));
  6469.     } elif (sea_value == BAD)
  6470.     {   strcat(line[LEFTSIDE][index], GetCatalogStr(li.li_Catalog, MSG_NO, "No"));
  6471.     } else
  6472.     {   // assert(sea_value == GOOD);
  6473.         strcat(line[LEFTSIDE][index], GetCatalogStr(li.li_Catalog, MSG_SPECIAL, "Special"));
  6474. }   }
  6475.  
  6476. MODULE void print_hagall(SLONG hagall_value, SLONG index)
  6477. {   strcpy(line[LEFTSIDE][index], "Hagall (");
  6478.     strcat(line[LEFTSIDE][index], GetCatalogStr(li.li_Catalog, MSG_SLOWED, "slowed"));
  6479.     strcat(line[LEFTSIDE][index], ")?");
  6480.     pad(line[LEFTSIDE][index]);
  6481.     if (hagall_value)
  6482.     {   strcat(line[LEFTSIDE][index], GetCatalogStr(li.li_Catalog, MSG_YES, "Yes"));
  6483.     } else
  6484.     {   strcat(line[LEFTSIDE][index], GetCatalogStr(li.li_Catalog, MSG_NO, "No"));
  6485. }   }
  6486.  
  6487. MODULE void print_paralyzed(SLONG loseturn_value, SLONG index)
  6488. {   strcpy(line[LEFTSIDE][index], GetCatalogStr(li.li_Catalog, MSG_PARALYZED, "Paralyzed"));
  6489.     strcat(line[LEFTSIDE][index], "?");
  6490.     pad(line[LEFTSIDE][index]);
  6491.     if (loseturn_value)
  6492.     {   strcat(line[LEFTSIDE][index], GetCatalogStr(li.li_Catalog, MSG_YES, "Yes"));
  6493.     } else
  6494.     {   strcat(line[LEFTSIDE][index], GetCatalogStr(li.li_Catalog, MSG_NO, "No"));
  6495. }   }
  6496.  
  6497. MODULE void amiga_attack(SLONG attackhero, SLONG defendtype, SLONG defender)
  6498. {   SLONG whichattack, whichjarl;
  6499.  
  6500.     // ok, going ahead with the battle
  6501.     if (defendtype == JARL && jarl[defender].face == FACEDOWN)
  6502.     {   revealjarl(defender, TRUE);
  6503.     }
  6504.     if (hero[attackhero].attacking)
  6505.     {   for (whichattack = 0; whichattack <= ATTACKS; whichattack++)
  6506.         {   if (hero[attackhero].attacktype[whichattack] == -1)
  6507.             {   hero[attackhero].attacktype[whichattack] = defendtype;
  6508.                 hero[attackhero].attacked[whichattack]   = defender;
  6509.                 break;
  6510.     }   }   }
  6511.     for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
  6512.     {   if (jarl[whichjarl].attacking)
  6513.         {   for (whichattack = 0; whichattack <= ATTACKS; whichattack++)
  6514.             {   if (jarl[whichjarl].attacktype[whichattack] == -1)
  6515.                 {   jarl[whichjarl].attacktype[whichattack] = defendtype;
  6516.                     jarl[whichjarl].attacked[whichattack]   = defender;
  6517.                     break;
  6518.     }   }   }   }
  6519.  
  6520.     saywho(HERO, attackhero, FALSE, FALSE);
  6521.     strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_ATTACKS, "attacks"));
  6522.  
  6523.     if (defendtype == HERO || defendtype == JARL)
  6524.     {   saywho(defendtype, defender, FALSE, TRUE);
  6525.     } elif (defendtype == MONSTER)
  6526.     {   strcat(saystring, " ");
  6527.         strcat(saystring, monstertypes[monster[defender].species]);
  6528.         strcat(saystring, " ");
  6529.         strcat(saystring, monster[defender].name);
  6530.     } else
  6531.     {   // assert(defendtype == KINGDOM);
  6532.         strcat(saystring, " ");
  6533.         if (world[defender].hero != -1)
  6534.         {   strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_HERO2, "hero"));
  6535.             strcat(saystring, " ");
  6536.             strcat(saystring, hero[world[defender].hero].name);
  6537.             strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_S, "'s"));
  6538.             strcat(saystring, " ");
  6539.         }
  6540.         strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_KINGDOM, "kingdom"));
  6541.         strcat(saystring, " ");
  6542.         strcat(saystring, world[defender].name);
  6543.         strcat(saystring, " (");
  6544.         stcl_d(numberstring, world[defender].tax);
  6545.         strcat(saystring, numberstring);
  6546.         strcat(saystring, ")");
  6547.     }
  6548.  
  6549.     strcat(saystring, ".");
  6550.     say(LOWER);
  6551.     anykey();
  6552.     dobattle(defendtype, defender, attackhero);
  6553. }
  6554.  
  6555. MODULE FLAG ask_faxi(SLONG countertype, SLONG whichcounter)
  6556. {   SLONG result;
  6557.  
  6558.     saywho(countertype, whichcounter, TRUE, FALSE);
  6559.     strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_RIDE_THE, "ride the"));
  6560.     strcat(saystring, " ");
  6561.     strcat(saystring, treasure[FREYFAXI].name);
  6562.     strcat(saystring, " (");
  6563.     stcl_d(numberstring, faxirides);
  6564.     strcat(saystring, numberstring);
  6565.     strcat(saystring, " ");
  6566.     strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_RIDES2, "rides"));
  6567.     strcat(saystring, ") (");
  6568.     strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_CHAR_YES, "Y"));
  6569.     strcat(saystring, "/");
  6570.     strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_CHAR_NO, "N"));
  6571.     strcat(saystring, ")?");
  6572.     say(LOWER);
  6573.  
  6574.     do
  6575.     {    result = getevent(KEYBOARD, NULL);
  6576.     } while (result != onekey[ONEKEY_YES] && result != onekey[ONEKEY_NO]);
  6577.     if (result == onekey[ONEKEY_YES])
  6578.     {   faxirides--;
  6579.         faxi_disappear();
  6580.         return(TRUE);
  6581.     }
  6582.     return(FALSE);
  6583. }
  6584.  
  6585. MODULE void saywho(SLONG countertype, SLONG counter, FLAG comma, FLAG lowercase)
  6586. {   if (!lowercase)
  6587.     {   saystring[0] = 0;
  6588.     } else
  6589.     {   strcat(saystring, " ");
  6590.     }
  6591.     if (countertype == HERO)
  6592.     {   if (!lowercase)
  6593.         {   strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_HERO, "Hero"));
  6594.         } else
  6595.         {   strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_HERO2, "hero"));
  6596.         }
  6597.         strcat(saystring, " ");
  6598.         strcat(saystring, hero[counter].name);
  6599.     } else
  6600.     {   // assert(countertype == JARL);
  6601.         if (jarl[counter].hero != -1)
  6602.         {   if (!lowercase)
  6603.             {   strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_HERO, "Hero"));
  6604.             } else
  6605.             {   strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_HERO2, "hero"));
  6606.             }
  6607.             strcat(saystring, " ");
  6608.             strcat(saystring, hero[jarl[counter].hero].name);
  6609.             strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_S_JARL, "'s jarl"));
  6610.         } else
  6611.         {   if (!lowercase)
  6612.             {   strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_JARL, "Jarl"));
  6613.             } else
  6614.             {   strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_JARL2, "jarl"));
  6615.         }   }
  6616.         strcat(saystring, " ");
  6617.         strcat(saystring, jarl[counter].name);
  6618.     }
  6619.     if (!lowercase)
  6620.     {   if (comma)
  6621.         {   strcat(saystring, ",");
  6622.         }
  6623.         strcat(saystring, " ");
  6624. }   }
  6625.  
  6626. MODULE FLAG attackersleft(void)
  6627. {   SLONG whichhero, whichjarl;
  6628.  
  6629.     for (whichhero = 0; whichhero <= HEROES; whichhero++)
  6630.     {   if (hero[whichhero].attacking)
  6631.         {   return(TRUE);
  6632.     }   }
  6633.     for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
  6634.     {   if (jarl[whichjarl].attacking)
  6635.         {   return(TRUE);
  6636.     }   }
  6637.     return(FALSE);
  6638. }
  6639.  
  6640.